【753. 破解保险箱】
来源:力扣(LeetCode)
描述:
有一个需要密码才能打开的保险箱。密码是 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" 也能打开保险箱。
提示:
- n 的范围是 [1, 4]。
- k 的范围是 [1, 10]。
- kn 最大可能为 4096。
方法: Hierholzer 算法
Hierholzer 算法可以在一个欧拉图中找出欧拉回路。
具体地,我们将所有的 n − 1 位数作为节点,共有 kn−1 个节点,每个节点有 kk 条入边和出边。如果当前节点对应的数为 a1 a2 ⋯ an−1,那么它的第 x 条出边就连向数 a2 ⋯ an−1x 对应的节点。这样我们从一个节点顺着第 x 条边走到另一个节点,就相当于输入了数字 x。
在某个节点对应的数的末尾放上它的某条出边的编号,就形成了一个 n 位数,并且每个节点都能用这样的方式形成 k 个 n 位数。
例如 k = 4,n = 3 时,节点分别为 00, 01, 02, ⋯, 32, 33,每个节点的出边的编号分别为 0, 1, 2, 3,那么 00 和它的出边形成了 000, 001, 002, 003 这 4 个 3 位数,32 和它的出边形成了 320, 321, 322, 323 这 4 个 3 位数。
这样共计有 kn−1 × k = kn 个 n 位数,恰好就是所有可能的密码。
由于这个图的每个节点都有 k 条入边和出边,因此它一定存在一个欧拉回路,即可以从任意一个节点开始,一次性不重复地走完所有的边且回到该节点。因此,我们可以用 Hierholzer 算法找出这条欧拉回路:
设起始节点对应的数为 uu,欧拉回路中每条边的编号为 x1, x2, x3, ⋯,那么最终的字符串即为
u x 1x 2x 3
Hierholzer 算法如下:
- 我们从节点 u 开始,任意地经过还未经过的边,直到我们「无路可走」。此时我们一定回到了节点 u,这是因为所有节点的入度和出度都相等。
- 回到节点 u 之后,我们得到了一条从 u 开始到 u 结束的回路,这条回路上仍然有些节点有未经过的出边。我么从某个这样的节点 v 开始,继续得到一条从 v 开始到 v 结束的回路,再嵌入之前的回路中,即
u → ⋯ → v → ⋯ → u
变为
u → ⋯ → v → ⋯ → v → ⋯ → u
以此类推,直到没有节点有未经过的出边,此时我们就找到了一条欧拉回路。
实际的代码编写具有一定的技巧性。
代码:
class Solution {private:unordered_set<int> seen;string ans;int highest;int k;public:void dfs(int node) {for (int x = 0; x < k; ++x) {int nei = node * 10 + x;if (!seen.count(nei)) {seen.insert(nei);dfs(nei % highest);ans += (x + '0');}}}string crackSafe(int n, int k) {highest = pow(10, n - 1);this->k = k;dfs(0);ans += string(n - 1, '0');return ans;}
};
执行用时:4 ms, 在所有 C++ 提交中击败了86.44%的用户
内存消耗:9 MB, 在所有 C++ 提交中击败了30.51%的用户
复杂度分析
时间复杂度:O(n×kn )。
空间复杂度:O(n×kn )。
author:LeetCode-Solution
【753. 破解保险箱】相关推荐
- Leetcode 753. 破解保险箱 C++
Leetcode 753. 破解保险箱 题目 有一个需要密码才能打开的保险箱.密码是 n 位数, 密码的每一位是 k 位序列 0, 1, -, k-1 中的一个 . 你可以随意输入密码,保险箱会自动记 ...
- Java实现 LeetCode 753 破解保险箱(递归)
753. 破解保险箱 有一个需要密码才能打开的保险箱.密码是 n 位数, 密码的每一位是 k 位序列 0, 1, -, k-1 中的一个 . 你可以随意输入密码,保险箱会自动记住最后 n 位输入,如果 ...
- 753. 破解保险箱
有一个需要密码才能打开的保险箱.密码是 n 位数, 密码的每一位是 k 位序列 0, 1, ..., k-1 中的一个 . 你可以随意输入密码,保险箱会自动记住最后 n 位输入,如果匹配,则能够打开保 ...
- LeetCode 753. 破解保险箱(有向欧拉图,计算机译码)
有一个需要密码才能打开的保险箱.密码是 n 位数, 密码的每一位是 k 位序列 0, 1, -, k-1 中的一个 . 你可以随意输入密码,保险箱会自动记住最后 n 位输入,如果匹配,则能够打开保险箱 ...
- LeetCode-753. 破解保险箱
题目链接:753. 破解保险箱 很日常,没看题解之前依然没有发现这是道图论的题目(每日一题从官方题解开始=.=).第一次在OJ练习上做到图论的题,之前做图论的题都是辛辛苦苦写了好多结构体然后按点按边做 ...
- leetcode-753: 破解保险箱
leetcode-753: 破解保险箱 题目 解题 方法一:Hierholzer 算法 题目 题目链接 有一个需要密码才能打开的保险箱.密码是 n 位数, 密码的每一位是 k 位序列 0, 1, -, ...
- 自制机器人15分钟破解保险箱密码
去年圣诞节,内森·赛德的妻子给了他一个从Graigslist上淘来的二手保险箱.乍一看,好像是个奇怪的礼物.这对夫妻已经有了同型号的SentrySafe防火保险箱,从家得宝花120美元买的.但这个,有 ...
- 我是如何使用自制机器人在15分钟内破解保险箱密码的?
本文讲的是 我是如何使用自制机器人在15分钟内破解保险箱密码的?, 亮相Def Con大会 热辣的7月,安全圈有两场最为火爆的顶级信息会议在美国拉斯维加斯拉开帷幕,它们分别是美国黑帽大会BlackHa ...
- JAVA程序设计:破解保险箱(LeetCode:753)
有一个需要密码才能打开的保险箱.密码是 n 位数, 密码的每一位是 k 位序列 0, 1, ..., k-1 中的一个 . 你可以随意输入密码,保险箱会自动记住最后 n 位输入,如果匹配,则能够打开保 ...
最新文章
- 博世力士乐液压_[Event Review] Company Visit Bosch Rexroth 博世力士乐液压工厂参观
- Web 应用服务器端渲染入门指南
- CSS每日学习笔记(0)
- shopxo首页右侧的登录注册板块:如何隐藏或删除?
- 浏览器之本地缓存存储 localStorage 和 sessionStorage的区别以及用法
- Resx 文件无效。未能加载 .RESX 文件中使用的类型 System.Collections.Generic.List`1请确保已在项目中添加了必需的引用。
- 文件怎么更新_iOS13屏蔽更新描述文件失效了怎么办?iOS13屏蔽系统更新教程
- 腾讯云坚持“云+数据库”转型,看好多模数据库未来发展
- html制作文字效果,10个text-shadow制作的文字效果
- html之常用input type
- 5A通过PMP考试分享
- 《DOOM启示录》读后感
- PS批量导出ios、android图标
- java设置字体大小_java中控制字体大小的设置
- 阿里P9专家右军:以终为始的架构设计
- 什么是GPU,GPU怎么工作的,什么是图形的渲染,渲染怎么完成的。
- 大长今人物系列:宿命中的孤独灵魂——崔今英(转载)
- 内部类与外部类之间的访问
- 嵌入式测试大赛实例解析
- SCI论文写作的过程中,功能强大工具有哪些? - 易智编译EaseEditing
热门文章
- Boost 学习之算法篇 mismatch
- 快手小店后台数据爬取(selenium+openpyxl)
- 手机怎么伪原创火山小视频 本地短视频去水印在线
- Snipaste常用快捷键(详细总结)
- vue项目打包出错:Unexpected token arrow «=>», expected punc «,» [static/js/chunk-1558f5a0.b64bfa00.js:626,2
- 「镁客·请讲」打造一台眼睛专属“跑步机”,鹰视菲诺是如何用AI拯救近视的?...
- AI萃取的5G咖啡,只有华为能调出这个味道
- 别人笑我太疯癫,我笑别人看不穿
- 俞敏洪:人生最重要的两件事是什么?
- [AutoVue开发手册]第二篇——AutoVue之Applet参数列表