LeetCode-python 753.破解保险箱

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


有一个需要密码才能打开的保险箱。密码是 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.破解保险箱)