Leetcode---電話號碼的字母組合--回溯
阿新 • • 發佈:2018-12-05
電話號碼的字母組合
題目連結:電話號碼的字母組合
分析:
- 第一次接觸回溯的題目,沒有什麼頭緒,題目看似簡單,本以為簡單的多重for迴圈即可搞定,仔細思考發現各種問題
- 首先digits.length是可變的,那麼對於digits的每一位數字,我們都需要到另一個字串陣列中查詢可選字元,所以,我們需要digits.length重迴圈語句,簡單的for迴圈的巢狀,是處理不了的,而深度遞迴可以。
- 沒有達到目標層數繼續遞迴,達到層數,則找到了一個可行解,追加至結果集,達到第i層時,我們進行遍歷第i層所有可能取值的情況,進行遞迴,遞迴結束後要回到上一層,選擇一個同級的下一個字元,這裡遞迴自動彈棧,但是我們應當清除之前追加的該層的字元。
//定義陣列對應的陣列,回溯和解題的函式都要用到,定義為靜態
static String[] manue = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
//定義一個暫存的字串,用於記錄每種結果
static StringBuffer sb = new StringBuffer();
public List<String> letterCombinations(String digits) {
//回溯演算法
//直接進行多層迴圈不可行是因為,digits的長度未知,而需要的是digits.length 次迴圈遍歷進行匹配
//定義一個結果集
List<String> result = new ArrayList<String>();
//沒有輸入就返回空
if(digits==null||digits.length()==0) {
return result;
}
//目標遞迴層數
int len = digits.length();
//呼叫回溯
traceback(manue,0,result,len,digits);
return result;
}
public void traceback(String[] manue,int i,List< String> result,int n,String digits) {
//已經達到遞迴的目標層數
if(i>=n) {
//此時sb為一個滿足條件的字串,追加至結果集
result.add(sb.toString());
return;
}
//當前層有幾種可選擇的字元,遍歷
for(int j=0;j<manue[digits.charAt(i)-'0'].length();j++) {
//追加第j個字元
sb.append(manue[digits.charAt(i)-'0'].charAt(j));
//當前層已經選擇完畢,繼續進行下一層遞迴
traceback(manue,i+1,result,n,digits);
//刪掉追加的字元,選擇同級的下一個字元,相當於返回到上一層,使用另一個同級字元
sb.deleteCharAt(sb.length()-1);
}
}