35、破解保险箱

题目描述:
有一个需要密码才能打开的保险箱。密码是 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]。
k^n 最大可能为 4096。

总共有k^n中可能,也就是将这些可能拼接成最短的字符串,这个字符串要包含所有的组合,比如n=k=2
那么组合的过程就是
00
001
0011
00110
这样的结果是最短的,也就是我们每次取n-1的长度,然后从最大的进行拼接,set是存放所有的可能,如果没有那么放进去,跳出循坏,然后继续取出n-1的长度

比如:
n=2,k=3那么过程就是
00
002
0022
00221
002212
0022120
00221201
002212011
0022120110
0022120110
这样的字符串时最短的

class Solution {
    public String crackSafe(int n, int k) {
        // 先计算总共有多少种可能
		int sumnum = (int) Math.pow(k, n);
		// set里面存放所有的排序结果
		Set<String> set = new HashSet<>();
		// 初始化放入的是n个0的排序
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < n; i++) {
			sb.append("0");
		}
		set.add(sb.toString());
		for (int i = 1; i < sumnum; i++) {
			String temString = sb.substring(sb.length() - n + 1);
			for (int j = k - 1; j >= 0 ; j--) {
				String tem = temString + j;
				if(!set.contains(tem)){
					sb.append(j);
					set.add(tem);
                  	break;
				}
			}
		}
		return sb.toString();
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值