【LeetCode】753. 破解保险箱

news2025/1/11 12:47:08

753. 破解保险箱

题目描述

有一个需要密码才能打开的保险箱。密码是 n 位数, 密码的每一位是 k 位序列 0, 1, ..., k-1 中的一个 。

你可以随意输入密码,保险箱会自动记住最后 n 位输入,如果匹配,则能够打开保险箱。

举个例子,假设密码是 “345”,你可以输入 “012345” 来打开它,只是你输入了 6 个字符.

请返回一个能打开保险箱的最短字符串。

原文:

There is a safe protected by a password. The password is a sequence of n digits where each digit can be in the range [0, k - 1].

The safe has a peculiar way of checking the password. When you enter in a sequence, it checks the most recent n digits that were entered each time you type a digit.

For example, the correct password is "345" and you enter in "012345":
- After typing 0, the most recent 3 digits is "0", which is incorrect.
- After typing 1, the most recent 3 digits is "01", which is incorrect.
- After typing 2, the most recent 3 digits is "012", which is incorrect.
- After typing 3, the most recent 3 digits is "123", which is incorrect.
- After typing 4, the most recent 3 digits is "234", which is incorrect.
- After typing 5, the most recent 3 digits is "345", which is correct and the safe unlocks.

Return any string of minimum length that will unlock the safe at some point of entering it.

示例 1

Input: n = 1, k = 2

Output: “10”

Explanation: The password is a single digit, so enter each digit. “01” would also unlock the safe.

示例 2

Input: n = 2, k = 2
Output: “01100”
Explanation: For each possible password:

  • “00” is typed in starting from the 4th digit.
  • “01” is typed in starting from the 1st digit.
  • “10” is typed in starting from the 3rd digit.
  • “11” is typed in starting from the 2nd digit.
    Thus “01100” will unlock the safe. “01100”, “10011”, and “11001” would also unlock the safe.

提示

1 <= n <= 4
1 <= k <= 10
1 <= kn <= 4096

算法一:贪心

思路

  • 题意转换:「求出一个最短的字符串,使其包含从 0∼kn(k进制)中的所有数字」,即将所有的 n−1 位数作为节点。每个节点有 k 条边,节点上添加数字 0∼ k−1 视为一条边。

    举例说明,如 n=3, k=2(三位二进制数),其节点(二位二进制数)为 “00”,“01”,“10”,“11” ,每个节点有 2 条边,节点上添加数字 0∼1 可转化到自身或另一个节点,如下图所示。

    在这里插入图片描述

  • 如果我们从任一节点出发,能够找出一条路径,经过图中的所有边且只经过一次,然后把边上的数字写入字符串(还需加入起始节点的数字),那么这个字符串显然符合要求,而且找不出比它更短的字符串了。

  • 从任一节点开始,从 0∼k−1 遍历,只要有可用的路就走,直到无法继续为止。 当我们无路可走时,一定是在起始点,并且起始点的所有边都已经过。 这是因为所有节点的入度和出度均为 k 。如果我们不在起始点,那 “只要有进去的路,就一定还有至少一条出去的路”。

  • 再看之前出现的无路可走的情况,我们发现,起始点回的太早了。从贪心的角度来想,如果可以 尽可能晚返回起始点,就能遍历更多的边。

  • 如果实现这个算法呢?

    我们选择 “00” 作为起始点。每次要选择添加的数字时,从大数字开始(即从 k−1 遍历到 0),这样可以尽可能晚地回到起始点。

  • 如何得到下一个节点的下标

    即解释 idx = (idx * k + edge) % nodeNum;

    对于一个 k 进制数,如果当前节点对应的数为 a1 a2 ⋯ an−1,那么它的第 x 条出边就连向数 a2 ⋯ an−1 x 对应的节点(下一个节点),那么下一个节点如何表示呢? (这里节点和下标是等价的)

    想象一下 10 进制,如何 9846 – x = 9 --> 8469
    显然就是 8469 = (9846 * 10 + 9) % 10000
    如果是 k 进制,那么就是 a2⋯an−1x = (a1a2⋯an−1 * k + x) % nodeNum

收获

  • 这道题涉及到 欧拉路径Hierholzer 算法 ,具体介绍见参考资料3 。解法一倒是没怎么涉及这些知识,用了 贪心 的思想,原理挺好理解的,但是代码难懂,尤其是下一个节点的下标计算,我看了很多解释才明白,解法一的正确性证明见参考资料 1。

算法情况

  • 时间复杂度:O(kn
  • 空间复杂度:O(kn

代码

class Solution {
public:
	string crackSafe(int n, int k) {
		//k的n-1次方个节点,每个节点有k条出边,所以图有k的n次方条边。
		int edgesNum = pow(k, n), nodeNum = pow(k, n - 1);
		//数组node是用来存储每个节点的出边,出边用索引表示,最大索引是k-1
		vector<int> node(nodeNum, k - 1);
		//这里多出来的n-1,其实是因为要初始化第一个节点"00..0"
		string s(edgesNum + (n - 1), '0');
        //idx表示节点索引
		for (int i = n - 1, idx = 0; i < s.size(); ++i) {
			int edge = node[idx];
			s[i] = edge + '0';
			//将对应的边出栈
			node[idx]--;
			//一共k^(n-1)个节点,可以看作n-2位的k进制数能表示的数,
			//即最小为0,最大为k^(n-1) - 1 (想象一下10进制,比如10^2,就好理解了)
			//如果当前节点对应的数为a1,a2,⋯,an−1,那么它的第x条出边就连向数 a2,⋯,an−1,x对应的节点
			//那么计算通向的下一个节点,需要先对当前的数进行左移操作(即在数值右端补0)
			//所以先 * k, 然后加上出边x,最后再通过 % 来抹去高位的a1。
			idx = (idx * k + edge) % nodeNum;
		}
		return s;
	}
};

算法二:Hierholzer 算法

思路

收获

算法情况

  • 时间复杂度
  • 空间复杂度

代码

参考资料:

  1. 一步一步推导出 0ms 解法(贪心构造)

  2. Cpp 详解 题目背景+Hierholzer 算法

  3. 欧拉路径和Hierholzer算法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/154095.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

怎么看电脑配置?Windows和Mac系统配置的查看方法

电脑的配置一般指电脑硬件配件的高档程度和性价比&#xff0c;计算机的性能主要取决于主要的硬件配置。很多朋友在购买电脑之前应该注意查看电脑的配置&#xff0c;怎么看电脑配置&#xff1f;下面有关于Windows系统和Mac系统电脑配置的不同查看方式&#xff0c;一起来看看吧&a…

光遗传学应用中所涉及到的光纤产品盘点!

如上图所示&#xff0c;在光遗传学的应用中&#xff0c;会使用到如光遗传跳线、光遗传插芯针、光纤旋转器、光纤耦合器/分束器&#xff08;12或22&#xff09;等产品。对于这些产品&#xff0c;根据不同的应用&#xff0c;又涉及到光纤芯径、数值孔径NA、出纤长度、插芯直径等众…

如何拖拽图片放到指定的格子里

本文首发于微信公众号&#xff1a; 小蚂蚁教你做游戏。欢迎关注领取更多学习做游戏的原创教程资料&#xff0c;每天学点儿游戏开发知识。嗨&#xff01;大家好&#xff0c;我是小蚂蚁。今天来分享一个如何在游戏中拖拽一个图片&#xff0c;然后把它放到指定的格子里&#xff0c…

网络编程(十)——基于UDP协议的套接字

TCP和UDP协议传输对比 TCP协议传输数据可靠&#xff0c;TCP传输数据后&#xff0c;如果收到接收方回应消息&#xff0c;则会在本机缓存中删除已发送消息&#xff1b;如果没有收到接收方回应消息&#xff0c;则会利用缓存继续发送消息。UDP协议传输数据相对来说不可靠&#xff…

学生看书用白炽灯和led灯哪个好?学生led护眼灯排行榜

我们都知道学生的晶状体是比较敏感的&#xff0c;不得不承认一个实际问题&#xff0c;LED灯已经普遍到日常生活中&#xff0c;不管是教室、企业、书房&#xff0c;使用LED灯居多&#xff0c;主要是因为它的电流稳定、光线柔和、光效效率高&#xff0c;所以LED灯的灯光没有紫外线…

Qt OpenGL(07)递归细分四面体法绘制球体

文章目录Qt OpenGL通过递归细分逼近球面思路下面就是绘制的代码&#xff1a;Widget.cpp顶点着色器片段着色器Qt OpenGL通过递归细分逼近球面 在OpenGL中绘制球面&#xff0c;不是太简单的事情。因为球面和圆都不是OpenGL所支持的图元&#xff0c;因此我们将通过一种称为递归细分…

飞宇科技在创业板IPO终止:长江证券撤回保荐,吴玉飞为实控人

2023年1月10日&#xff0c;深圳证券交易所披露的信息显示&#xff0c;江苏飞宇医药科技股份有限公司&#xff08;下称“飞宇科技”&#xff09;的保荐机构&#xff08;长江证券&#xff09;提交了撤回飞宇科技首次公开发行股票并在创业板上市申请的申请因此&#xff0c;深圳证券…

BOM(二): 元素偏移量offset 、元素可视区client 、元素滚动 scroll、动画

PC端网页特效元素偏移量offset元素可视区client元素滚动 scroll 系列动画元素偏移量offset 1.offset概述 offset 系列相关属性可以动态的得到该元素的位置&#xff08;偏移&#xff09;、大小等。 获得元素距离带有定位父元素的位置获得元素自身的大小&#xff08;宽度高度&…

Python 字典(Dictionary)操作详解

这篇文章主要介绍了Python 字典(Dictionary)的详细操作方法&#xff0c;需要的朋友可以参考下。 Python字典是另一种可变容器模型&#xff0c;且可存储任意类型对象&#xff0c;如字符串、数字、元组等其他容器模型。 一、创建字典 字典由键和对应值成对组成。字典也被称作关…

微信小程序云开发之新闻博客社区项目debug后的项目代码

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a;lqj_本人的博客_CSDN博客-微信小程序,html特效,vue2基础领域博主 本次文章主要时为我最近在哔哩哔哩上的新发布的视频做一个映射&#xff01; 哔哩哔哩欢迎关注&#xff1a;小淼前端 哔…

【Python从入门到进阶】3、运行python代码

接上篇《2、Python环境的安装》 上一篇我们学习了如何下载安装Python编程环境&#xff0c;以及如何使用pip管理Python包。本篇我们来学习如何使用终端和执行文件运行python代码。 一、终端运行 我们可以在命令行终端进入python解释程序&#xff0c;直接输入python代码&#x…

Spring Cloud OpenFeign @SpringQueryMap注解

概述 我们在使用GetMapping方法是&#xff0c;对于多个参数都是通过RequestParam参数一个一个接取的&#xff0c;多个参数时会比较麻烦&#xff0c;能像RequestBody那样接取PostMapping的参数么&#xff1f;答案是可以的。 SpringQueryMap介绍 SpringQueryMap 注解是 spring…

关于数据管理、数据治理和数据资产,你搞得清楚吗?

全球数字化的趋势愈演愈烈&#xff0c;我国信息化规模日渐增大&#xff0c;我们也每天都在接收大量的数据&#xff0c;要想深度挖掘数据的价值&#xff0c;首先从搞清楚数据的概念入手。今天我们就来聊一聊数据管理、数据治理和数据资产的概念和它们之间的相互关系。 数据管理…

从低代码来看,何谓客户体验自动化

在当今竞争激烈的大环境下&#xff0c;拥有出色的产品或服务并不意味着100%成功&#xff0c;反而是客户在购买流程中的体验变得比以往任何时候都更加重要。 随着企业业务的发展&#xff0c;提供个性化的客户体验变得愈加困难&#xff0c;许多企业因无法提供令人满意的客户体验而…

JavaScript 与 C++ 的差异

在正式开始向各位前端开发者介绍 C 语言之前&#xff0c;我们先讨论一下 C 语言与 JavaScript 语言的差异&#xff08;为了约束讨论的范围&#xff0c;这里就不提 HTML 和 CSS 了&#xff09;。 C 语言于 1979 年由贝尔实验室的 Bjarne Stroustrup&#xff08;本贾尼斯特劳斯特…

【web安全】——HTTP请求头注入

作者名&#xff1a;Demo不是emo主页面链接&#xff1a; 主页传送门创作初心&#xff1a; 舞台再大&#xff0c;你不上台&#xff0c;永远是观众&#xff0c;没人会关心你努不努力&#xff0c;摔的痛不痛&#xff0c;他们只会看你最后站在什么位置&#xff0c;然后羡慕或鄙夷座右…

uni-app开发常用点

前言 应该会不定时更新&#xff0c;主要记录自己在uni-app开发过程中经常用到的东西。 组件库推荐&#xff1a; 1、https://v1.uviewui.com/ 我们老项目用到是这个的1.x版本&#xff0c;新版本没用过 2、https://vant-contrib.gitee.io/vant/v2/#/zh-CN/ 3、https://uniapp.d…

智能在线客服系统源码 国际版多语言多商户智能机器人源码

一套智能在线客服系统源码 多商户网页客服系统源码 支持二十种国际语言 带机器人自动回复。 框架&#xff1a;Thinkphp5workerman&#xff0c; 环境&#xff1a;nginxphp7.3mysql5.6 支持H5公众号APP小程序 私信了解更多源码内容&#xff01; 系统功能特点&#xff1a; 1、…

k8s创建数据库

参考配置1 [rootk8s-master1 ~]# cat deployment.yaml apiVersion: apps/v1 kind: Deployment metadata:labels:app: mysql #为该Deployment设置key为app&#xff0c;value为mysql的标签name: mysqlnamespace: test spec:replicas: 1 #副本数量selector: #标签选择器&#xf…

深挖你拥有的东西的背后的价值到底是什么,价值转换模型分析。

深挖你拥有的东西的背后的价值到底是什么。 我们先把它转换成为观众观看这条视频的动机&#xff0c;甚至是观众关注账号的动机。 例如你能帮助别人赚钱&#xff0c;你能帮助别人变美。你提供的价值是成长的价值&#xff0c;你提供的价值是精神追求的价值&#xff0c;是生活理念…