回溯——第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);
        }
    }

 

posted @ 2021-12-06 17:06  Mirror559  阅读(34)  评论(0)    收藏  举报