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:

  1. n will be in the range [1, 4].
  2. k will be in the range [1, 10].
  3. k^n will be at most 4096.

这道题说的是给了k个数字,值为0到k-1,可以组成n位密码。让我们找一个万能钥匙串,能破解任意的n位密码组合,这里对于破解的定义为只要密码是钥匙串的子串就可以破解了,要求出最短的一个万能钥匙串。来看一个例子,n=2,k=2,那么密码的组合有四种,

,,,

所以 00110 就是一种钥匙串,因为密码  (110),  (010),  (001),  (000), 分别都包括在钥匙串中。可以发现,为了尽可能的使钥匙串变短,所以密码之间尽可能要相互重叠,比如 00 和 01,就共享一个0,如果是3个数,012 和 120 共享两个数 "12",再进一步们可以发现,两个长度为n的密码最好能共享 n-1 个数字,这样累加出来的钥匙串肯定是最短的。

密码共有n位,每一个位可以有k个数字,总共不同的密码总数就有k的n次方个。思路是先从n位都是0的密码开始,取出钥匙串的最后 n-1 个数字,然后在后面依次添加其他数字,用一个 HashSet 来记录所有遍历过的密码,这样如果不在集合中,说明是一个新密码,而生成这个新密码也只是多加了一个数字,能保证钥匙串最短,这是一种贪婪的解法,相当的巧妙,就拿题目中的例子2来说明吧,n=2, k=2,最多有4个密码。开始时 res 初始化为 00,需要遍历4次。第一次遍历时,先取出最后一个数字0,此时先尝试再后面添加1,可组成新密码 01,不在 HashSet 中,将其加入 HashSet,并且将这个1加到 res 后面,变为 001,然后断开内部 for 循环。开始进行第2次遍历,取出 res 中最后一个数字1,先尝试在后面添加1,可组成新密码 11,不在 HashSet 中,将其加入 HashSet,并且将这个1加到 res 后面,变为 0011,然后断开内部 for 循环。开始进行第3次遍历,取出 res 中最后一个数字1,先尝试在后面添加1,可组成密码 11,已在 HashSet 中,跳过;尝试在后面添加0,可组成密码 10,不在 HashSet 中,将其加入 HashSet,并且将这个0加到 res 后面,变为 00110,然后断开内部 for 循环。开始进行第4次遍历,取出 res 中最后一个数字0,先尝试在后面添加1,可组成密码 01,已在 HashSet 中,跳过;再尝试在后面添加0,可组成密码 00,已在 HashSet 中,跳过,循环结束。这样最终的 res 为 00110 即为符合题意的万能钥匙,参见代码如下:

解法一:

class Solution {
public:
string crackSafe(int n, int k) {
string res = string(n, '');
unordered_set<string> visited{{res}};
for (int i = ; i < pow(k, n); ++i) {
string pre = res.substr(res.size() - n + , n - );
for (int j = k - ; j >= ; --j) {
string cur = pre + to_string(j);
if (!visited.count(cur)) {
visited.insert(cur);
res += to_string(j);
break;
}
}
}
return res;
}
};

来看同一种解法的递归写法,思路和迭代的写法一模一样,写法略有不同而已,参见代码如下:

解法二:

class Solution {
public:
string crackSafe(int n, int k) {
string res = string(n, '');
unordered_set<string> visited{{res}};
helper(n, k, pow(k, n), visited, res);
return res;
}
void helper(int n, int k, int total, unordered_set<string>& visited, string& res) {
if (visited.size() == total) return;
string pre = res.substr(res.size() - n + , n - );
for (int i = k - ; i >= ; --i) {
string cur = pre + to_string(i);
if (visited.count(cur)) continue;
visited.insert(cur);
res += to_string(i);
helper(n, k, total, visited, res);
}
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/753

参考资料:

https://leetcode.com/problems/cracking-the-safe/

https://leetcode.com/problems/cracking-the-safe/discuss/110264/Easy-DFS

https://leetcode.com/problems/cracking-the-safe/discuss/112966/C++-greedy-loop-from-backward-with-explaination

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] 753. Cracking the Safe 破解密码的更多相关文章

  1. [LeetCode] Cracking the Safe 破解密码

    There is a box protected by a password. The password is n digits, where each letter can be one of th ...

  2. 【LeetCode】753. Cracking the Safe 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/cracking ...

  3. 753. Cracking the Safe

    There is a box protected by a password. The password is n digits, where each letter can be one of th ...

  4. 如何破解密码的哈希值,破解双MD5密码值

    这是关于我如何破解密码的哈希值1亿2200万* John the Ripper和oclHashcat-plus故事. 这是几个月前,当我看到一条推特:从korelogic约含共1亿4600万个密码的密 ...

  5. windows下hashcat利用GPU显卡性能破解密码

    由于一般密码破解工具的破解速度实在是太慢,而且支持的密码破解协议也不多,暴力破解的话,有的密码1年时间也破不出来,用字典跑的话必须要明文密码在字典里才行,而且密码字典太大的话,也很浪费时间,跑不出来也 ...

  6. 为什么现在更多需要用的是 GPU 而不是 CPU,比如挖矿甚至破解密码?

    作者:Cascade链接:https://www.zhihu.com/question/21231074/answer/20701124来源:知乎著作权归作者所有,转载请联系作者获得授权. 想要理解G ...

  7. 暴力枚举 + 24点 --- hnu : Cracking the Safe

    Cracking the Safe Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit u ...

  8. python 暴力破解密码脚本

    python 暴力破解密码脚本 以下,仅为个人测试代码,环境也是测试环境,暴力破解原理都是一样的, 假设要暴力破解登陆网站www.a.com 用户 testUser的密码, 首先,该网站登陆的验证要支 ...

  9. 破解密码那些事儿(Hacking Secret Ciphers with Python)

    作者:Al Sweigart   我们在电视和电影里头经常能够看到黑客们兴奋的快速敲击键盘,接着毫无意义的数字就在屏幕上飞奔(比如黑客帝国).然后让大家产生了一种奇妙的错觉,做黑客是一件高大上的事情, ...

随机推荐

  1. Anaconda--在虚拟环境中安装CUDA and cudnn

    在conda虚拟环境中安装CUDAconda install cudatoolkit=8.0 -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs ...

  2. dbvisualizer客户端执行创建存储过程或自定义函数语句的方法

    DBVisualizer这个数据库客户端工具,如果要执行存储过程或函数的话,需要在创建存储过程或函数的语句的最前面和末尾分别加上[--/]和[/]符号. --/ CREATE FUNCTION B22 ...

  3. Python3.0的新特性

    网上关于Python3与Python2的区别的文章都烂大街了,但基本上都是抄来抄去,为了追本溯源,直接看官网最靠谱,官网文档的结构性更强. 本文是对Python3.0官网文档 What's New I ...

  4. jakarta-oro-2.0.8.jar-----------JAVA FTP相关

    资源不好找,找到了就和大家分享一下! 链接:https://share.weiyun.com/51kBB0y 密码:2hcxcu

  5. 4-consul HTTP API及实践

    其他参考:https://www.cnblogs.com/duanxz/p/9660766.html 原文:https://www.douban.com/note/629645759/ 注意:使用AP ...

  6. webpack4 plugins 篇

    demo 代码点此,篇幅有限,仅介绍几个常用的. start 什么是 plugins ? While loaders are used to transform certain types of mo ...

  7. web自动化测试

    自动化测试主要分为下面三种: 1.单元测试(Unit Test) 对单独的代码块,比如函数进行测试.单元测试是自动化测试的主要形式,也是最基本的形式. 2.集成测试(Integration Test) ...

  8. pip python

    简介 pip 是一个安装和管理 Python 包的工具,python安装包的工具有easy_install, setuptools, pip,distribute.使用这些工具都能下载并安装djang ...

  9. Android Studio 3.5+ 使用androidx的recyclerView

    一 File->project structure->Dependencies: 点击All Dependencies处的加号,选择Library Dependency: 在step1处输 ...

  10. 21个React开发神器

    摘要: React开发神器. 原文:22 Miraculous Tools for React Developers in 2019 译者:前端小智 下列工具中的重要性与排序无关. 1.Webpack ...