回溯——第77題. 組合 part.2
阿新 • • 發佈:2021-12-06
在寫了77和216之後,發現我的回溯函式每次都需要在主函式中增加一層迴圈,讓回溯的過程從起點開始,這跟遞迴的用法有著非常大的區別。
於是我看了一下題解,發現了自己在回溯上的問題:
1 public void function(int n, int k, int curr) { 2 //在進入回溯函式的開頭,就將路徑上的節點加入到回溯記錄中 3 //這樣就相當於總體的回溯過程是從回溯樹的第二層開始的 4 //第一層的值已經被直接add了 5 temp.add(curr); 6 7 System.out.println(temp.toString());8 if (temp.size() == k) { 9 result.add((ArrayList<Integer>) temp.clone()); 10 } 11 else { 12 if (temp.size() + n-curr >= k) { 13 for (int next = curr+1; next <= n; ++next) { 14 function(n, k, next); 15 }16 } 17 } 18 temp.remove(temp.size()-1); 19 }
因此需要把回溯路徑的記錄過程放到回溯函式的單層邏輯中:
private void combineHelper(int n, int k, int startIndex){ //終止條件 if (temp.size() == k){ result.add(new ArrayList<>(temp)); return; }for (int i = startIndex; i <= n - (k - temp.size()) + 1; i++){ //在單層邏輯中再進行路徑的記錄,這樣才能讓回溯從正確的起點,即回溯樹的第一層開始 //在本題中,就是temp陣列的第一個元素能正確的1,2,3,...變更 temp.add(i); combineHelper(n, k, i + 1); temp.remove(temp.size()-1); } }