回溯——216.组合总和III

跟77基本上是一样的思路,因为回溯还不是很熟练,在主函数中还是忘记了需要加入加入一层循环

第一次解法:

    public void function(int k, int sum, int currNum, int currSum) {
        temp.add(currNum);
        //System.out.println(temp.toString());
        currSum += currNum;

        if (temp.size() == k) {
            if (currSum == sum) {
                result.add((ArrayList<Integer>) temp.clone());
            }
        } else {
            //剪枝:currSum + nextNum <= sum
            //下一个数不能和currSum相加之后超过sum,这样之后的数必不符合要求
            for (int nextNum = currNum+1; currSum + nextNum <= sum  && nextNum <= 9; ++nextNum) {
                function(k, sum, nextNum, currSum);
            }
        }

        temp.remove(temp.size()-1);
    }

在主函数中需要如下循环:

  for (int currNum = 1; currNum < sum && currNum < 10; ++currNum) { function(k, sum, currNum, 0); } 

后来看了题解,发现其实回溯函数可以独自完成这个过程:

    private void backtracking(int k, int sum, int currNum, int currSum) {
        if (temp.size() == k) {
            if (currSum == sum) {
                result.add((ArrayList<Integer>) temp.clone());
            }
            return ;
        }
        
        // currSum += currNum;
        // System.out.println(currSum);
        for (int number = currNum; currSum + number <= sum && number <= 9; ++number) {
            temp.add(number);
            //System.out.println(temp.toString());
            backtracking(k, sum, number+1, currSum + number);
            temp.remove(temp.size()-1);
        } 
    }

这种回溯方法,相当于从回溯树的root开始,每次遍历到这个节点才加入path,就不会有重复or遗漏。

posted @ 2021-12-09 10:44  Mirror559  阅读(29)  评论(0)    收藏  举报