|
| 1 | +/** |
| 2 | + * DP | Recursion | Memoization |
| 3 | + * Time O(n^4) | Space O(n^4) |
| 4 | + * https://leetcode.com/problems/string-compression-ii/ |
| 5 | + * @param {string} s |
| 6 | + * @param {number} k |
| 7 | + * @return {number} |
| 8 | + */ |
| 9 | +function getLengthOfOptimalCompression(s, k) { |
| 10 | + const cache = new Map(); |
| 11 | + |
| 12 | + const dfs = (i, pre, freqOfSameChar, leftK) => { |
| 13 | + |
| 14 | + const hash = `${i},${pre},${freqOfSameChar},${leftK}`; |
| 15 | + if (cache.has(hash)) return cache.get(hash); |
| 16 | + |
| 17 | + if (leftK < 0) return Infinity; |
| 18 | + if (i === s.length) return 0; |
| 19 | + |
| 20 | + const deleteChar = dfs(i+1, pre, freqOfSameChar, leftK-1); |
| 21 | + |
| 22 | + let keepChar; |
| 23 | + |
| 24 | + if (s[i] === pre) { |
| 25 | + |
| 26 | + const addOneOrZero = (freqOfSameChar === 1 || freqOfSameChar === 9 || freqOfSameChar === 99) ? 1 : 0; |
| 27 | + keepChar = addOneOrZero + dfs(i+1, pre, freqOfSameChar + 1, leftK); |
| 28 | + } else { |
| 29 | + |
| 30 | + keepChar = 1 + dfs(i+1, s[i], 1, leftK); |
| 31 | + } |
| 32 | + |
| 33 | + cache.set(hash, Math.min(deleteChar, keepChar)); |
| 34 | + |
| 35 | + return cache.get(hash); |
| 36 | + } |
| 37 | + |
| 38 | + return dfs(0, -1, 0, k); |
| 39 | +} |
| 40 | + |
| 41 | + |
| 42 | +/** |
| 43 | + * Brute force. |
| 44 | + * Time O(2^n) | Space O(n) |
| 45 | + * https://leetcode.com/problems/string-compression-ii |
| 46 | + * @param {string} s |
| 47 | + * @param {number} k |
| 48 | + * @return {number} |
| 49 | + */ |
| 50 | +var getLengthOfOptimalCompressionBF = function(s, k) { |
| 51 | + |
| 52 | + const runLengthEncoded = (str) => { |
| 53 | + const encodedStr = []; |
| 54 | + let left = 0; |
| 55 | + let right = 1; |
| 56 | + |
| 57 | + while(right < str.length + 1) { |
| 58 | + while(str[left] === str[right]) { |
| 59 | + right++; |
| 60 | + } |
| 61 | + const len = right - left; |
| 62 | + if(len > 1) { |
| 63 | + encodedStr.push(str[left], len); |
| 64 | + } else { |
| 65 | + encodedStr.push(str[left]) |
| 66 | + } |
| 67 | + |
| 68 | + left = right; |
| 69 | + right++; |
| 70 | + } |
| 71 | + |
| 72 | + return encodedStr.join("").length; |
| 73 | + } |
| 74 | + |
| 75 | + let min = Infinity; |
| 76 | + const dfs = (i, str, deleteLeft) => { |
| 77 | + // console.log(str) |
| 78 | + const hash = `${i}-${deleteLeft}`; |
| 79 | + |
| 80 | + if(i === s.length) { |
| 81 | + min = Math.min(min, runLengthEncoded(str)) |
| 82 | + return; |
| 83 | + } |
| 84 | + if(deleteLeft > 0) { |
| 85 | + return Math.min(dfs(i+1, str+s[i], deleteLeft), dfs(i+1, str, deleteLeft-1)); |
| 86 | + } |
| 87 | + return dfs(i+1, str+s[i], deleteLeft); |
| 88 | + } |
| 89 | + |
| 90 | + dfs(0, "", k); |
| 91 | + return min; |
| 92 | +}; |
0 commit comments