[LeetCode] 753. Cracking the Safe 破解密码
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 most4096
.
这道题说的是给了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
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] 753. Cracking the Safe 破解密码的更多相关文章
- [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 ...
- 【LeetCode】753. Cracking the Safe 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/cracking ...
- 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 ...
- 如何破解密码的哈希值,破解双MD5密码值
这是关于我如何破解密码的哈希值1亿2200万* John the Ripper和oclHashcat-plus故事. 这是几个月前,当我看到一条推特:从korelogic约含共1亿4600万个密码的密 ...
- windows下hashcat利用GPU显卡性能破解密码
由于一般密码破解工具的破解速度实在是太慢,而且支持的密码破解协议也不多,暴力破解的话,有的密码1年时间也破不出来,用字典跑的话必须要明文密码在字典里才行,而且密码字典太大的话,也很浪费时间,跑不出来也 ...
- 为什么现在更多需要用的是 GPU 而不是 CPU,比如挖矿甚至破解密码?
作者:Cascade链接:https://www.zhihu.com/question/21231074/answer/20701124来源:知乎著作权归作者所有,转载请联系作者获得授权. 想要理解G ...
- 暴力枚举 + 24点 --- hnu : Cracking the Safe
Cracking the Safe Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit u ...
- python 暴力破解密码脚本
python 暴力破解密码脚本 以下,仅为个人测试代码,环境也是测试环境,暴力破解原理都是一样的, 假设要暴力破解登陆网站www.a.com 用户 testUser的密码, 首先,该网站登陆的验证要支 ...
- 破解密码那些事儿(Hacking Secret Ciphers with Python)
作者:Al Sweigart 我们在电视和电影里头经常能够看到黑客们兴奋的快速敲击键盘,接着毫无意义的数字就在屏幕上飞奔(比如黑客帝国).然后让大家产生了一种奇妙的错觉,做黑客是一件高大上的事情, ...
随机推荐
- Anaconda--在虚拟环境中安装CUDA and cudnn
在conda虚拟环境中安装CUDAconda install cudatoolkit=8.0 -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs ...
- dbvisualizer客户端执行创建存储过程或自定义函数语句的方法
DBVisualizer这个数据库客户端工具,如果要执行存储过程或函数的话,需要在创建存储过程或函数的语句的最前面和末尾分别加上[--/]和[/]符号. --/ CREATE FUNCTION B22 ...
- Python3.0的新特性
网上关于Python3与Python2的区别的文章都烂大街了,但基本上都是抄来抄去,为了追本溯源,直接看官网最靠谱,官网文档的结构性更强. 本文是对Python3.0官网文档 What's New I ...
- jakarta-oro-2.0.8.jar-----------JAVA FTP相关
资源不好找,找到了就和大家分享一下! 链接:https://share.weiyun.com/51kBB0y 密码:2hcxcu
- 4-consul HTTP API及实践
其他参考:https://www.cnblogs.com/duanxz/p/9660766.html 原文:https://www.douban.com/note/629645759/ 注意:使用AP ...
- webpack4 plugins 篇
demo 代码点此,篇幅有限,仅介绍几个常用的. start 什么是 plugins ? While loaders are used to transform certain types of mo ...
- web自动化测试
自动化测试主要分为下面三种: 1.单元测试(Unit Test) 对单独的代码块,比如函数进行测试.单元测试是自动化测试的主要形式,也是最基本的形式. 2.集成测试(Integration Test) ...
- pip python
简介 pip 是一个安装和管理 Python 包的工具,python安装包的工具有easy_install, setuptools, pip,distribute.使用这些工具都能下载并安装djang ...
- Android Studio 3.5+ 使用androidx的recyclerView
一 File->project structure->Dependencies: 点击All Dependencies处的加号,选择Library Dependency: 在step1处输 ...
- 21个React开发神器
摘要: React开发神器. 原文:22 Miraculous Tools for React Developers in 2019 译者:前端小智 下列工具中的重要性与排序无关. 1.Webpack ...