题目描述:
有一个需要密码才能打开的保险箱。密码是 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();}
}