leetcode-216. 组合总和 III(回溯+剪枝)

216. 组合总和 III

原题链接:https://leetcode.cn/problems/combination-sum-iii/
题解:https://leetcode.cn/problems/combination-sum-iii/solution/jian-zhi-kao-lu-bi-jiao-wan-shan-de-by-_-x5oa/

题目

找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:

只使用数字1到9
每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。

示例1

输入: k = 3, n = 7
输出: [[1,2,4]]
解释:
1 + 2 + 4 = 7
没有其他符合的组合了。

示例2

输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]
解释:
1 + 2 + 6 = 9
1 + 3 + 5 = 9
2 + 3 + 4 = 9
没有其他符合的组合了。

提示

  • 2 <= k <= 9
  • 1 <= n <= 60
分析

很明显的回溯题,遍历寻找符合条件的。因为是在1到9中寻找且每个数字最多使用一次,所以注意剪枝条件。

  1. 当path.size()>=k,即当前路径长度达到k,则不在遍历,停止
  2. 当剩下的path都选择当前节点i下的最小值(i,i+1…),结果和也大于n,停止
  3. 当前节点i到9的个数小于剩余节点个数,即9-i+1
代码
class Solution {
    public List<List<Integer>> res = new ArrayList<>();
    public List<Integer> path = new ArrayList<>();
    public List<List<Integer>> combinationSum3(int k, int n) {
        dfs(k, n, 1, 0);
        return res;
    }

    public void dfs(int k, int n, int index, int count) {
        if (count==n && path.size()==k){
            res.add(new ArrayList<>(path));
            return;
        }
        for (int i=index;i<=9;i++) {
            if (path.size()>=k) break;
            if (count+(k-path.size()-1+2*i)*(k-path.size())/2>n || 10-i<k-path.size()) break;
            path.add(i);
            dfs(k, n, i+1, count+i);
            path.remove(path.size()-1);
        }
    }
}
结果

时间超过100%

内存超过95%

你可能感兴趣的:(leetcode,leetcode,剪枝,算法)