美文网首页
LeetCode-python 753.破解保险箱

LeetCode-python 753.破解保险箱

作者: wzNote | 来源:发表于2019-09-25 11:43 被阅读0次

    题目链接
    难度:困难       类型: 深度优先搜索


    有一个需要密码才能打开的保险箱。密码是 n 位数, 密码的每一位是 k 位序列 0, 1, ..., k-1 中的一个 。

    你可以随意输入密码,保险箱会自动记住最后 n 位输入,如果匹配,则能够打开保险箱。

    举个例子,假设密码是 "345",你可以输入 "012345" 来打开它,只是你输入了 6 个字符.

    请返回一个能打开保险箱的最短字符串。

    示例1

    输入: n = 1, k = 2
    输出: "01"
    说明: "10"也可以打开保险箱。

    示例2

    输入: n = 2, k = 2
    输出: "00110"
    说明: "01100", "10011", "11001" 也能打开保险箱。

    解题思路


    密码接龙

    这道题说的是给了k个数字,值为0到k-1,让我们组成n位密码。我们可以发现,为了尽可能的使钥匙串变短,所以我们的密码之间尽可能要相互重叠,

    比如00和01,就共享一个0,
    如果是3个数,012和120共享两个数”12”,
    那么我们可以发现,两个长度为n的密码最好能共享n-1个数字,这样累加出来的钥匙串肯定是最短的。

    密码共有n位,每一个位可以有k个数字,那么总共不同的密码总数就有k的n次方个。我们的思路是先从n位都是0的密码开始,取出钥匙串的最后n个数字,然后将最后一个数字依次换成其他数字,我们用一个Set来记录所有遍历过的密码,这样如果不在集合中,说明是一个新密码,而生成这个新密码也只是多加了一个数字,这样能保证我们的钥匙串最短

    1. 初始一个最小的可能的n-1位的密码,即n-1个0
    2. 最后一位依次添加0到k-1,组成的n位密码如果未出现过,就把最后一位加入res,并且把这n位密码加入集合seen,表示已经出现过这个密码
    3. 然后取该n位密码的后n-1位, 进行第2步
    4. 最后把所有res中的数串起来,再接上n-1个0,接在后面的原因是这段代码用到递归,输出的值是倒序的

    代码实现

    class Solution(object):
        def crackSafe(self, n, k):
            """
            :type n: int
            :type k: int
            :rtype: str
            """
            seen = set()
            res = []
            def dfs(node):
                for x in map(str, range(k)):
                    nei = node + x
                    if nei not in seen:
                        seen.add(nei)
                        dfs(nei[1:])
                        res.append(x)
            dfs('0'*(n-1))
            return ''.join(res) + '0'*(n-1)
    

    本文链接:https://www.jianshu.com/p/6f51c036cb0e

    相关文章

      网友评论

          本文标题:LeetCode-python 753.破解保险箱

          本文链接:https://www.haomeiwen.com/subject/keneectx.html