753. Cracking the Safe
by Botao Xiao
753. Cracking the Safe
Question
There is a box protected by a password. The password is n digits, where each letter can be one of the first k digits 0, 1, …, k-1.
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.
Solutions
- Method 1: DFS: Hamiltonion path.
- Hamilton path question is visiting all of the states without repeating.
- What’s the path between the states in this question?
- For each state, its length is n, and next node can re-use previous node’s last n - 1 characters.
- for example, we have 0 and 1 to use.
- first node is 00, second reuses 0 and append 0 or 1.
- Analyse this question
- If we cannot re-use previous node, we have total length of (k ^ n) * n
- Since we can re-use previous node’s n - 1 character, we have the total length of k ^ n + n - 1
class Solution { private int expect; // total length of result. private int k; private int n; public String crackSafe(int n, int k) { this.expect = (int)Math.pow((double)k, (double)n) + n - 1; this.k = k; this.n = n; StringBuilder res = new StringBuilder(); for(int i = 0; i < n; i++) res.append(0); Set<String> visited = new HashSet<>(); visited.add(res.toString()); dfs(res, visited); return res.toString(); } private boolean dfs(StringBuilder sb, Set<String> visited){ if(sb.length() == expect) return true; // sb currently saves the string and we will reuse last n - 1 characters. String pre = sb.substring(sb.length() - n + 1); for(char c = '0'; c < '0' + k; c++){ String current = pre + c; if(visited.contains(current)) continue; visited.add(current); sb.append(c); if(dfs(sb, visited)) return true; sb.deleteCharAt(sb.length() - 1); visited.remove(current); } return false; } }
Subscribe via RSS