technology-note/算法/leetcode/常规题/Q216.组合总和 3.md
2022-03-10 17:23:59 +08:00

69 lines
2.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: "202203103"
date: "2022/03/10 22:15"
title: "Q216 组合总和3(combination-sumⅢ)"
tags: ["java", "leetcode", "dfs"]
index_img: https://qiniupic.fleyx.com/blog/202203101631050.jpg?imageView2/2/w/200
banner_img: https://qiniupic.fleyx.com/blog/202203101631050.jpg
categories:
- "算法"
- "leetcode刷题"
---
<span id="blogIdSpan" style="display:none">202203103</span>
## 解析思路
leetcode 中等难度,题目描述[点击这里](https://leetcode-cn.com/problems/combination-sum-iii/)。
本题属于[组合排序 2](https://blog.fleyx.com/blog/detail/202203102/)的进阶题型。建议先看[上一篇](https://blog.fleyx.com/blog/detail/202203102/)的解析。
本题跟上一题区别只有一点是**选择的数字不能重复**,**同时对选择的数量有限制**如何实现呢?
很简单,只需要
- 将传入的 index 设置成 index+1实现不重复
- ~~同时 for 循环时每次都循环到下一个不同的元素上~~由于本来提供的数字就不重复,因此可以去掉这一条
- 循环和返回结果是都判断下元素数量
代码如下:
## 代码
```java
public class Q216 {
public List<List<Integer>> combinationSum3(int k, int n) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};
List<List<Integer>> res = new ArrayList<>();
dfs(arr, n, k, 0, new Stack<>(), res);
return res;
}
private void dfs(int[] candidates, int n, int k, int index, Stack<Integer> temp, List<List<Integer>> res) {
if (n == 0) {
//说明找到一个结果序列
if (temp.size() == k) {
//只有刚好k个数才是结果
res.add(new ArrayList<>(temp));
}
return;
}
for (int i = index; i < candidates.length; i++) {
if (candidates[i] > n || temp.size() == k) {
//前面已经排序过所以在这里可以进行剪枝操作如果candidates[index]都小于target了那就不需要比较后面的了肯定不满足要求
//另外只能使用k个数所以当temp的size为k时说明不能在装了本条路结束
return;
}
temp.push(candidates[i]);
dfs(candidates, n - candidates[i], k, i + 1, temp, res);
temp.pop();
}
}
public static void main(String[] args) {
new Q216().combinationSum3(3, 9).forEach(System.out::println);
}
}
```