Description
Write a function to generate the generalized abbreviations of a word.
**Note: **The order of the output does not matter.
Example:
Input:
"word"
Output:
["word", "1ord", "w1rd", "wo1d", "wor1", "2rd", "w2d", "wo2", "1o1d", "1or1", "w1r1", "1o2", "2r1", "3d", "w3", "4"]
Solution
Backtracking, O(n * 2 ^ n), S(n)
Complexity Analysis
Time complexity : O(n * 2^n). For each call to backtrack, it either returns without branching, or it branches into two recursive calls. All these recursive calls form a complete binary recursion tree with 2^n leaves and 2^n - 1 inner nodes. For each leaf node, it needs O(n) time for converting builder to String; for each internal node, it needs only constant time.
Thus, the total time complexity is dominated by the leaves. In total that is O(n * 2^n).
Space complexity : O(n). If the return list doesn't count, we only need O(n) auxiliary space to store the characters in StringBuilder and the O(n) space used by system stack. In a recursive program, the space of system stack is linear to the maximum recursion depth which is n in our problem.
题意很好理解,对于word中的每个位置来说,都有缩写和不缩写两种选择,所以总共有2 ^ n中选择。很自然想到利用backtracking来构造所有组合。
class Solution {
public List<String> generateAbbreviations(String word) {
List<String> res = new ArrayList<>();
dfs(word, 0, new StringBuilder(), 0, res);
return res;
}
private void dfs(String word, int pos
, StringBuilder sb, int count, List<String> res) {
int originalLen = sb.length(); // keep original sb state
if (pos >= word.length()) {
sb.append(count > 0 ? count : ""); // don't forget to append count
res.add(sb.toString()); // cost O(n)!!
} else {
// abbreviate
dfs(word, pos + 1, sb, count + 1, res);
// don't abbreviate
sb.append(count > 0 ? count : ""); // append previous abbr chars count
sb.append(word.charAt(pos)); // append current char
dfs(word, pos + 1, sb, 0, res); // reset count to 0
}
sb.setLength(originalLen); // reset sb to original state
}
}
Bit-manipulation, O(n * 2 ^ n), S(n)
虽然题目里没给定word的长度限制,但我猜测不会很大,因为这道题的时间复杂度一定是指数级的,word太长会TLE。于是可以用bit manipulation去穷举所有选择,这样写也是很清晰的。
class Solution {
public List<String> generateAbbreviations(String word) {
List<String> res = new ArrayList<>();
for (int i = 0; i < (1 << word.length()); ++i) {
res.add(getAbbr(word, i));
}
return res;
}
private String getAbbr(String word, int bits) {
StringBuilder sb = new StringBuilder();
int count = 0;
for (int i = 0; i < word.length(); ++i, bits >>= 1) {
if ((bits & 1) == 0) {
sb.append(count > 0 ? count : "")
.append(word.charAt(i));
count = 0;
} else {
++count;
}
}
sb.append(count > 0 ? count : "");
return sb.toString();
}
}
网友评论