Write a function to generate the generalized abbreviations of a word.app
Example:
Given word = "word", return the following list (order does not matter):ui["word", "1ord", "w1rd", "wo1d", "wor1", "2rd", "w2d", "wo2", "1o1d", "1or1", "w1r1", "1o2", "2r1", "3d", "w3", "4"]
O(2^N) 時間 O(N) 空間this
是子集問題的一個變種,拿到例子一開始沒明白,爲何沒有"22","1111",後來仔細一想,"22"就是"4","1111"也是"4"。
思路以下:
拿到一個String的word,從頭至尾依次對於每個char,能夠選擇縮寫也能夠不縮寫:
回溯方法的interface:3d
void explore(int cur, //該處理哪一個字符?進來的一剎那(或者說進來以前),cur並無被處理 StringBuilder sb, //進來的一剎那或者說進來以前(cur還未被考慮)的已有前綴 int count, //進來的一剎那或進來以前(cur還未被考慮)cur前面還未結束的縮寫數 List<String> result, //存最後的結果 String word) //輸入,不用解釋
對每一個char,若是選擇縮寫它,不要馬上把他寫成1append在stringbuilder裏,由於萬一後面的也選擇縮寫那麼這兩個字符就得縮寫成"2"。因此一旦選擇縮寫一個字符,別把他變成數字,記下來,累積着,直到對於下一個字符咱們選擇不縮寫(或到頭了,即一直縮寫到最後一個字符),再把以前累計的縮寫的個數append在stringbuilder裏。code
public class Solution { public List<String> generateAbbreviations(String word) { List<String> result = new ArrayList<String>(); StringBuilder sb = new StringBuilder(); explore(0, sb, 0, result, word); return result; } public void explore(int cur, StringBuilder sb, int count, List<String> result, String word) { //到頭了,返回條件 if (cur == word.length()) { int i = sb.length(); if (count != 0) { sb.append(count); } result.add(sb.toString()); sb.delete(i, sb.length()); return; } //abrv this char explore(cur + 1, sb, count + 1, result, word); //keep this char int i = sb.length(); if (count != 0) { sb.append(count); } sb.append(word.charAt(cur)); explore(cur + 1, sb, 0, result, word); sb.delete(i, sb.length()); } }