|
| 1 | +/** |
| 2 | + * 2014. Longest Subsequence Repeated k Times |
| 3 | + * https://leetcode.com/problems/longest-subsequence-repeated-k-times/ |
| 4 | + * Difficulty: Hard |
| 5 | + * |
| 6 | + * You are given a string s of length n, and an integer k. You are tasked to find the longest |
| 7 | + * subsequence repeated k times in string s. |
| 8 | + * |
| 9 | + * A subsequence is a string that can be derived from another string by deleting some or no |
| 10 | + * characters without changing the order of the remaining characters. |
| 11 | + * |
| 12 | + * A subsequence seq is repeated k times in the string s if seq * k is a subsequence of s, |
| 13 | + * where seq * k represents a string constructed by concatenating seq k times. |
| 14 | + * - For example, "bba" is repeated 2 times in the string "bababcba", because the string |
| 15 | + * "bbabba", constructed by concatenating "bba" 2 times, is a subsequence of the |
| 16 | + * string "bababcba". |
| 17 | + * |
| 18 | + * Return the longest subsequence repeated k times in string s. If multiple such subsequences |
| 19 | + * are found, return the lexicographically largest one. If there is no such subsequence, |
| 20 | + * return an empty string. |
| 21 | + */ |
| 22 | + |
| 23 | +/** |
| 24 | + * @param {string} s |
| 25 | + * @param {number} k |
| 26 | + * @return {string} |
| 27 | + */ |
| 28 | +var longestSubsequenceRepeatedK = function(s, k) { |
| 29 | + const n = s.length; |
| 30 | + const freq = new Array(26).fill(0); |
| 31 | + for (const char of s) { |
| 32 | + freq[char.charCodeAt(0) - 97]++; |
| 33 | + } |
| 34 | + |
| 35 | + let candidates = ''; |
| 36 | + for (let i = 0; i < 26; i++) { |
| 37 | + const count = Math.floor(freq[i] / k); |
| 38 | + candidates += String.fromCharCode(97 + i).repeat(count); |
| 39 | + } |
| 40 | + |
| 41 | + function canFormSubsequence(seq) { |
| 42 | + let j = 0; |
| 43 | + for (let i = 0; i < n && j < seq.length * k; i++) { |
| 44 | + if (s[i] === seq[j % seq.length]) j++; |
| 45 | + } |
| 46 | + return j >= seq.length * k; |
| 47 | + } |
| 48 | + |
| 49 | + let result = ''; |
| 50 | + backtrack('', candidates); |
| 51 | + return result; |
| 52 | + |
| 53 | + function backtrack(curr, remaining) { |
| 54 | + if (curr.length > result.length || (curr.length === result.length && curr > result)) { |
| 55 | + if (canFormSubsequence(curr)) result = curr; |
| 56 | + } |
| 57 | + if (!remaining) return; |
| 58 | + |
| 59 | + for (let i = remaining.length - 1; i >= 0; i--) { |
| 60 | + const nextChar = remaining[i]; |
| 61 | + backtrack(curr + nextChar, remaining.slice(0, i) + remaining.slice(i + 1)); |
| 62 | + } |
| 63 | + } |
| 64 | +}; |
0 commit comments