320. Generalized Abbreviation π
DifficultyMedium
Description
A word's generalized abbreviation can be constructed by taking any number of non-overlapping and non-adjacent substrings and replacing them with their respective lengths.
- For example,
"abcde"can be abbreviated into:"a3e"("bcd"turned into"3")"1bcd1"("a"and"e"both turned into"1")"5"("abcde"turned into"5")"abcde"(no substrings replaced)
- However, these abbreviations are invalid:
"23"("ab"turned into"2"and"cde"turned into"3") is invalid as the substrings chosen are adjacent."22de"("ab"turned into"2"and"bc"turned into"2") is invalid as the substring chosen overlap.
Given a string word, return a list of all the possible generalized abbreviations of word. Return the answer in any order.
Example 1:
Input: word = "word" Output: ["4","3d","2r1","2rd","1o2","1o1d","1or1","1ord","w3","w2d","w1r1","w1rd","wo2","wo1d","wor1","word"]
Example 2:
Input: word = "a" Output: ["1","a"]
Constraints:
1 <= word.length <= 15wordconsists of only lowercase English letters.
Solutions
Solution 1: DFS
Thinking
Each letter is kept or folded into a run of omitted counts. \(n\le 15\), so every scheme is enumerable.
\(dfs(i)\) handles the suffix: keep \(word[i]\) and recurse, or collapse \([i,j)\) into a number and append \(word[j]\) (if any) plus the rest. The empty suffix returns \([""]\) as the join base.
We design a function \(dfs(i)\), which returns all possible abbreviations for the string \(word[i:]\).
The execution logic of the function \(dfs(i)\) is as follows:
If \(i \geq n\), it means that the string \(word\) has been processed, and we directly return a list composed of an empty string.
Otherwise, we can choose to keep \(word[i]\), and then add \(word[i]\) to the front of each string in the list returned by \(dfs(i + 1)\), and add the obtained result to the answer.
We can also choose to delete \(word[i]\) and some characters after it. Suppose we delete \(word[i..j)\), then the \(j\) th character is not deleted, and then add \(j - i\) to the front of each string in the list returned by \(dfs(j + 1)\), and add the obtained result to the answer.
Finally, we call \(dfs(0)\) in the main function.
The time complexity is \(O(n \times 2^n)\), and the space complexity is \(O(n)\). Where \(n\) is the length of the string \(word\).
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Solution 2: Binary Enumeration
Thinking
The recursion matches the \(2^n\) keep/omit choices. A bit mask marks omitted positions; runs of \(1\)s become a count, a \(0\) emits the letter. The iterative form drops the call stack.
Since the length of the string \(word\) does not exceed \(15\), we can use the method of binary enumeration to enumerate all abbreviations. We use a binary number \(i\) of length \(n\) to represent an abbreviation, where \(0\) represents keeping the corresponding character, and \(1\) represents deleting the corresponding character. We enumerate all \(i\) in the range of \([0, 2^n)\), convert it into the corresponding abbreviation, and add it to the answer list.
The time complexity is \(O(n \times 2^n)\), and the space complexity is \(O(n)\). Where \(n\) is the length of the string \(word\).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |