原题链接在这里:https://leetcode.com/problems/generalized-abbreviation/
题目:
Write a function to generate the generalized abbreviations of a word.
Example:
Given word = "word"
, return the following list (order does not matter):
["word", "1ord", "w1rd", "wo1d", "wor1", "2rd", "w2d", "wo2", "1o1d", "1or1", "w1r1", "1o2", "2r1", "3d", "w3", "4"]
题解:
对于当前char有两个选择,第一缩写当前char, count+1, pos+1. 第二不缩写当前char, 先append 非零的count再append当前char, count回零, pos+1.
Backtracking时 sb被设定回原来的长度, 用setLength回开始的length.
Time Complexity: exponential. 在每一步递归时,有两个branches. 递归树全部展开会有2^n个叶子. 每一个叶子都相当于用了O(n)时长, 把StringBuilder变成String就用时O(n). n = word.length().
Space: O(n). n层stack, char array size也是n. regardless res.
AC Java:
1 public class Solution { 2 public List<String> generateAbbreviations(String word) { 3 List<String> res = new ArrayList<String>(); 4 dfs(word.toCharArray(), new StringBuilder(), res, 0, 0); 5 return res; 6 } 7 8 private void dfs(char [] s, StringBuilder sb, List<String> res, int count, int pos){ 9 int len = sb.length(); 10 if(pos == s.length){ 11 if(count != 0){ 12 sb.append(count); 13 } 14 res.add(sb.toString()); 15 }else{ 16 dfs(s, sb, res, count+1, pos+1); //abbr 当前字母 17 18 //不 abbr 当前字母 19 if(count != 0){ 20 sb.append(count); 21 } 22 dfs(s, sb.append(s[pos]), res, 0, pos+1); 23 } 24 sb.setLength(len); 25 } 26 }
Bit Manipulation 方法是用binary表示word的每一位. 0代表不缩写当前char, 1代表缩写当前char.
word 若是用 0011表示就是不缩写wo, 缩写rd, 最后是wo2.
对于word的所有binary表示, 也就是0000到1111走一遍,每个binary变成string.
Time Complexity: O(n*2^n). n = word.length(), 一共有O(2^n)个binary表示. 每个binary变成string用时O(n).
Space: O(n), regardless res.
AC Java:
1 public class Solution { 2 public List<String> generateAbbreviations(String word) { 3 List<String> res = new ArrayList<String>(); 4 if(word == null){ 5 return res; 6 } 7 int n = 1<<word.length(); 8 char [] s = word.toCharArray(); 9 for(int i = 0; i<n; i++){ 10 res.add(abbr(i, s)); 11 } 12 return res; 13 } 14 15 private String abbr(int num, char [] s){ 16 StringBuilder sb = new StringBuilder(); 17 int count = 0; 18 for(int i = 0; i<s.length; i++, num>>=1){ 19 // 0 表示不缩写当前char, 1 表示缩写当前char 20 if((num & 1) == 0){ 21 // 先加上之前的非零count, 再把count清零 22 if(count != 0){ 23 sb.append(count); 24 count = 0; 25 } 26 sb.append(s[i]); 27 }else{ 28 count++; 29 } 30 } 31 //最后的非零count不要忘记加进sb中 32 if(count != 0){ 33 sb.append(count); 34 } 35 return sb.toString(); 36 } 37 }