1. 程式人生 > 其它 >回溯——第77題. 組合 part.2

回溯——第77題. 組合 part.2

在寫了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); } }