回溯——第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); } }
                    
                
                
            
        
浙公网安备 33010602011771号