标签:first ati prot size 组合 one esc pad 复杂
Problem:
There is a box protected by a password. The password is n
digits, where each letter can be one of the first k
digits 0, 1, ..., k-1
.
You can keep inputting the password, the password will automatically be matched against the last n
digits entered.
For example, assuming the password is "345"
, I can open it when I type "012345"
, but I enter a total of 6 digits.
Please return any string of minimum length that is guaranteed to open the box after the entire string is inputted.
Example 1:
Input: n = 1, k = 2 Output: "01" Note: "10" will be accepted too.
Example 2:
Input: n = 2, k = 2 Output: "00110" Note: "01100", "10011", "11001" will be accepted too.
Note:
n
will be in the range [1, 4]
.k
will be in the range [1, 10]
.k^n
will be at most 4096
.
Solution:
这道题thumb down的次数大于thumb up的次数,可见这道题不是很好。对于这道题,总共有k^n
种可能的排列,我们现在要把它组合成一个长度为k^n
+n-1的字符串,使得所有的排列都是这个字符串的子串。对于这个问题,常规思路是用backtrace,其时间复杂度为k^(
k^n),时间复杂度相当高。而答案使用了一种贪心算法,对于下一个要添加的字符s[i],从大到小找到s[i-n+1]到s[i]的未使用过的子串,比如00之后,从1到0找到第一个未使用的子串01,将1添加到末尾变为001。虽然这个算法可行,但对于这道题来说,我们很难找到一种从暴力解法到可优化解法的思考过程,对于这个算法是否可行我们也没有办法证明。因此,对于这道题,我更多的觉得只要记住这种解法即可。
Code:
1 class Solution { 2 public: 3 string crackSafe(int n, int k) { 4 string res = string(n, ‘0‘); 5 unordered_set<string> visited{{res}}; 6 for (int i = 0; i < pow(k, n); ++i) { 7 string pre = res.substr(res.size() - n + 1, n - 1); 8 for (int j = k - 1; j >= 0; --j) { 9 string cur = pre + to_string(j); 10 if (!visited.count(cur)) { 11 visited.insert(cur); 12 res += to_string(j); 13 break; 14 } 15 } 16 } 17 return res; 18 } 19 };
Leetcode 753. Cracking the Safe
标签:first ati prot size 组合 one esc pad 复杂
原文地址:https://www.cnblogs.com/haoweizh/p/10262190.html