参考轻风舞动 的博客,网址:https://www.cnblogs.com/lightwindy/p/9847632.html
package algorithm;
import java.util.HashSet;
import java.util.Set;
/*
*
[LeetCode] 753. Cracking the Safe 破解密码
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 most 4096.
连续输入一串密码字符,每次输入一个会按最后一个字符开始匹配。给定密码长度为n,数字个数为k,k的值为0到k-1,用[0, k-1]的数字组成一个密码,使得这个密码一定能打开盒子,返回长度最短的一个密码。
思路:如果保证一定能打开箱子,输入的字符串要能覆盖所有的长度为n的字符串。其实是找到所有由[0, k-1]的数字组成的长度为n的组合,总共有k^n个组合。
解法:DFS
* */
public class CrackTheSafe {
public String crackSafe(int n, int k) {
StringBuilder sb = new StringBuilder();
int total = (int) (Math.pow(k, n)); //此为k的n次方
for (int i = 0; i < n; i++) sb.append('0');
Set
visited.add(sb.toString());
dfs(sb, total, visited, n, k);
return sb.toString();
}
private boolean dfs(StringBuilder sb, int goal, Set
if (visited.size() == goal) //当该字符串,包含n的所有的组合时,如n=2,k=2,包含4种,00,01,11,10时
return true;
String prev = sb.substring(sb.length() - n + 1, sb.length()); //前缀为除最后一个字符外,前面的前缀
for (int i = 0; i < k; i++) {
String next = prev + i;//添加最后一个字符
if (!visited.contains(next)) { //不包含,则说明新的值
visited.add(next);
sb.append(i);
if (dfs(sb, goal, visited, n, k)) //符合条件,都包含
return true;
else {
visited.remove(next); //不包含 回退,继续探索下一个字符
sb.delete(sb.length() - 1, sb.length());
}
}
}
return false;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
String result=new CrackTheSafe().crackSafe(2,2);
System.out.println("result="+result);
//String ss="ab";
//String hh=ss.substring(1, 2);
//System.out.println(hh);
}
}