LeetCode_Array_216. Combination Sum III 组合总和 III(C++/Java)

目录

1,题目描述

英文描述

中文描述

2,解题思路

3,AC代码

C++

Java

4,解题过程

第一博


1,题目描述

原题链接216. 组合总和 III

英文描述

Find all valid combinations of k numbers that sum up to n such that the following conditions are true:

Only numbers 1 through 9 are used.
Each number is used at most once.
Return a list of all possible valid combinations. The list must not contain the same combination twice, and the combinations may be returned in any order.

 

Example 1:

Input: k = 3, n = 7
Output: [[1,2,4]]
Explanation:
1 + 2 + 4 = 7
There are no other valid combinations.
Example 2:

Input: k = 3, n = 9
Output: [[1,2,6],[1,3,5],[2,3,4]]
Explanation:
1 + 2 + 6 = 9
1 + 3 + 5 = 9
2 + 3 + 4 = 9
There are no other valid combinations.
Example 3:

Input: k = 4, n = 1
Output: []
Explanation: There are no valid combinations. [1,2,1] is not valid because 1 is used twice.
Example 4:

Input: k = 3, n = 2
Output: []
Explanation: There are no valid combinations.
Example 5:

Input: k = 9, n = 45
Output: [[1,2,3,4,5,6,7,8,9]]
Explanation:
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 = 45
​​​​​​​There are no other valid combinations.
 

Constraints:

2 <= k <= 9
1 <= n <= 60

中文描述

找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。

说明:

所有数字都是正整数。
解集不能包含重复的组合。 
示例 1:

输入: k = 3, n = 7
输出: [[1,2,4]]
示例 2:

输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combination-sum-iii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2,解题思路

采用dfs递归+剪枝的方法,借助于堆栈来实现;

sum记录当前的累加和,depth记录当前数组中元素数目,tem记录当前存储的元素(dfs的路径),ans最终答案;

  • 出口:深度depth达到k,函数返回。当sum == n时,将tem加入ans;
  • 递归:for(int i = (tem.size() == 0 ? 1 : tem.back() + 1); i <= 9; i++),将i作为下一个元素,再次进行dfs(sum + i, depth + 1, n, k);
  • 剪枝:由于sum只增不减,所以当累加和大于n后,就可以终止for循环中的递归了 (使用break跳出);

注意dfs中,元素的插入和弹出时机(总是成对执行); 

过程较为简单,可以直接看代码

3,AC代码

C++

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> tem;
    vector<vector<int>> combinationSum3(int k, int n) {
        dfs(0, 0, n, k);
        return ans;
    }
    void dfs(int sum, int depth, int n, int k) {
        if(depth == k) {                // 数目达到限制(深度即数组中元素数目)
            if(sum == n) ans.push_back(tem);
            return;
        }
        for(int i = (tem.size() == 0 ? 1 : tem.back() + 1); i <= 9; i++) {
            if(sum + i > n) break;   // 剪枝 由于sum只增不减 当前之和大于n就没必要继续递归下去了
            tem.push_back(i);
            dfs(sum + i, depth + 1, n, k);
            tem.pop_back();
        }
    }
};

Java

Java解法参考@liweiwei1419【回溯 + 剪枝(Java)】

class Solution {
    public List<List<Integer>> ans = new ArrayList<>();
    // 根据官方对 Stack 的使用建议,这里将 Deque 对象当做 stack 使用
    // 注意只使用关于栈的接口
    public Deque<Integer> path = new ArrayDeque<>();
    public List<List<Integer>> combinationSum3(int k, int n) {
        dfs(0, 0, n, k);
        return ans;
    }
    public void dfs(int sum, int depth, int n, int k) {
        if(depth == k) {                // 数目达到限制(深度即数组中元素数目)
            if(sum == n) ans.add(new ArrayList<>(path));
            return;
        }
        for(int i = path.size() == 0 ? 1 : path.getLast() + 1; i <= 9; i++) {
            if(sum + i > n) break;      // 剪枝 由于sum只增不减 当前之和大于n就没必要继续递归下去了
            path.addLast(i);
            dfs(sum + i, depth + 1, n, k);
            path.removeLast();
        }
    }
}

4,解题过程

第一博

dfs递归实现,第一个数num1为[1, 9](表示从1到9),第二个数num2为[num1 + 1, 9],······第k个数numk为[numk-1 + 1, 9];

数据量比较小,所以速度还是很快的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值