1. 程式人生 > >Leetcode---電話號碼的字母組合--回溯

Leetcode---電話號碼的字母組合--回溯

電話號碼的字母組合

題目連結:電話號碼的字母組合

分析:
  • 第一次接觸回溯的題目,沒有什麼頭緒,題目看似簡單,本以為簡單的多重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); } }