|
| 1 | +/** |
| 2 | + * 753. Cracking the Safe |
| 3 | + * https://leetcode.com/problems/cracking-the-safe/ |
| 4 | + * Difficulty: Hard |
| 5 | + * |
| 6 | + * There is a safe protected by a password. The password is a sequence of n digits where each |
| 7 | + * digit can be in the range [0, k - 1]. |
| 8 | + * |
| 9 | + * The safe has a peculiar way of checking the password. When you enter in a sequence, it checks |
| 10 | + * the most recent n digits that were entered each time you type a digit. |
| 11 | + * |
| 12 | + * For example, the correct password is "345" and you enter in "012345": |
| 13 | + * - After typing 0, the most recent 3 digits is "0", which is incorrect. |
| 14 | + * - After typing 1, the most recent 3 digits is "01", which is incorrect. |
| 15 | + * - After typing 2, the most recent 3 digits is "012", which is incorrect. |
| 16 | + * - After typing 3, the most recent 3 digits is "123", which is incorrect. |
| 17 | + * - After typing 4, the most recent 3 digits is "234", which is incorrect. |
| 18 | + * - After typing 5, the most recent 3 digits is "345", which is correct and the safe unlocks. |
| 19 | + * |
| 20 | + * Return any string of minimum length that will unlock the safe at some point of entering it. |
| 21 | + */ |
| 22 | + |
| 23 | +/** |
| 24 | + * @param {number} n |
| 25 | + * @param {number} k |
| 26 | + * @return {string} |
| 27 | + */ |
| 28 | +var crackSafe = function(n, k) { |
| 29 | + if (n === 1) return Array.from({ length: k }, (_, i) => i).join(''); |
| 30 | + const seen = new Set(); |
| 31 | + const targetSize = k ** n; |
| 32 | + let sequence = '0'.repeat(n); |
| 33 | + |
| 34 | + seen.add(sequence); |
| 35 | + build(sequence); |
| 36 | + return sequence; |
| 37 | + |
| 38 | + function build(curr) { |
| 39 | + if (seen.size === targetSize) return true; |
| 40 | + |
| 41 | + const prefix = curr.slice(-n + 1); |
| 42 | + for (let digit = 0; digit < k; digit++) { |
| 43 | + const next = prefix + digit; |
| 44 | + if (!seen.has(next)) { |
| 45 | + seen.add(next); |
| 46 | + sequence += digit; |
| 47 | + if (build(sequence)) return true; |
| 48 | + sequence = sequence.slice(0, -1); |
| 49 | + seen.delete(next); |
| 50 | + } |
| 51 | + } |
| 52 | + return false; |
| 53 | + } |
| 54 | +}; |
0 commit comments