这道题是LeetCode里的第40道题。

题目要求:

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明:

  • 所有数字(包括目标数)都是正整数。
  • 解集不能包含重复的组合。

示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]

示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
  [1,2,2],
  [5]
]

解法和第39题几乎一样,区别在于本题每一个数字只能使用一次,但数字在数组中是可以重复的。同样,还是使用回溯剪枝法,先对 candidates 数组元素排序。排序后进行循环递归。具体代码如下:

提交代码:

class Solution {
public:
vector<vector<int>> res;
vector<int> ans;
void getres(vector<int>& candidates,int target,int k,vector<int> ans){
int size=candidates.size();
for(int i=k;i<size;i++){
if(target-candidates[i]>0){
if(i>k&&candidates[i]==candidates[i-1])continue;
ans.push_back(candidates[i]);
getres(candidates,target-candidates[i],i+1,ans);
ans.pop_back();
}
else if(target-candidates[i]<0){return;}
else{
ans.push_back(candidates[i]);
res.push_back(ans);
ans.pop_back();
return;
}
}
return;
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort(candidates.begin(),candidates.end());
getres(candidates,target,0,ans);
return res;
}
};

代码和第39题几乎一样,只改了两个地方,第一个是第11行,参数由 i 改为 i+1,这是能想到的确保每一个数字只使用一次的改法。但是这样改还并不完全,因为最终答案会有重复的解答。第二个改法纠结我好久:最笨的想法是先把解保存在一个 set 集合中,然后在转入 vector<vector<int>> 中,但这样太慢了,不想用。那么是什么原因造成解的重复呢?原因就是 candidates 数组中包含着重复数,例如:

示例1:candidates = [10,1,2,7,6,1,5],target = 8,标准解答:[[1,2,5],[1,7],[1,1,6],[2,6]]

没有第九行代码前的解答:[[1,1,6],[1,2,5],[1,7],[1,2,5],[1,7],[2,6]],其中第二个和第四个重复,第三个和第五个重复。因为数组中有两个1,这两个1分别组合了一次,造成了重复。知道原因了,就好解决,首先想到的是加入条件candidates[i]==candidates[i-1]当前后元素相等时,直接跳过本次循环,但问题又来了:[1,1,6]这个解,前后元素相等,但不重复,怎么办?这个我想了好久,最后看评论:因为当前层,如果再取下一个一样的数的话,就会造成重复,但是在下一层加入就不会,因为当前层是替换,如果拿一个一样的替换肯定会重复。再加入条件:i>k 就能保证既不会缺少[1,1,6]这个解,也保证了解的互异。所以第九行加入代码:if(i>k&&candidates[i]==candidates[i-1])continue;,然后剩下的剪枝第39题都有。

提交结果:

个人总结:

本题和第39题不同,难度也体现在最后答案的重复上。回溯法的本质还是递归,递归最难的地方就是容易弄混循环和递归层数,需要画图仔细分析,递归循环是个树图,画图也好容易分析。最后这题也可以不用排序,因为数字只使用一次,但是结果是会有重复的,而且重复的是无规则的,效率低。

【LeetCode】Combination Sum II(组合总和 II)的更多相关文章

  1. [LeetCode] Combination Sum IV 组合之和之四

    Given an integer array with all positive numbers and no duplicates, find the number of possible comb ...

  2. [LeetCode] Combination Sum III 组合之和之三

    Find all possible combinations of k numbers that add up to a number n, given that only numbers from ...

  3. 040 Combination Sum II 组合总和 II

    给定候选号码数组 (C) 和目标总和数 (T),找出 C 中候选号码总和为 T 的所有唯一组合.C 中的每个数字只能在组合中使用一次.注意:    所有数字(包括目标)都是正整数.    解决方案集不 ...

  4. Leetcode题库——40.组合总和II

    @author: ZZQ @software: PyCharm @file: combinationSum2.py @time: 2018/11/15 18:38 要求:给定一个数组 candidat ...

  5. 216 Combination Sum III 组合总和 III

    找出所有可能的 k 个数,使其相加之和为 n,只允许使用数字1-9,并且每一种组合中的数字是唯一的.示例 1:输入: k = 3, n = 7输出:[[1,2,4]]示例 2:输入: k = 3, n ...

  6. Leetcode之回溯法专题-40. 组合总和 II(Combination Sum II)

    Leetcode之回溯法专题-40. 组合总和 II(Combination Sum II) 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使 ...

  7. Java实现 LeetCode 40 组合总和 II(二)

    40. 组合总和 II 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的每个数字在 ...

  8. [LeetCode] 377. Combination Sum IV 组合之和 IV

    Given an integer array with all positive numbers and no duplicates, find the number of possible comb ...

  9. 40. 组合总和 II + 递归 + 回溯 + 记录路径

    40. 组合总和 II LeetCode_40 题目描述 题解分析 此题和 39. 组合总和 + 递归 + 回溯 + 存储路径很像,只不过题目修改了一下. 题解的关键是首先将候选数组进行排序,然后记录 ...

随机推荐

  1. 【转】常用邮箱的 IMAP/POP3/SMTP 设置

    POP3 POP3是Post Office Protocol 3的简称,即邮局协议的第3个版本,它规定怎样将个人计算机连接到Internet的邮件服务器和下载电子邮件的电子协议.它是因特网电子邮件的第 ...

  2. springMVC 与 struts+hibernate+spring优缺点

    springMVC: Spring 框架是高度可配置的,而且包含多种视图技术,例如 JavaServer Pages(JSP)技术.Velocity.Tiles.iText 和POI.Spring M ...

  3. vue从入门到开发--4--处理http请求

    一: 在main.js里面处理http请求模块,因为没有这个模块,所以需要先安装这个模块:npm install vue-resource --save 安装完毕之后,导入这个模块,并使用中间件将其使 ...

  4. 声明已被否决 VS C++

    error C4996声明已被否决,不止一次碰到这个问题,在这里必须mark一下! 尝试这个1.Project Properties > Configuration Properties > ...

  5. imageview加载本地和网络图片

    ImageView是Android程序中经常用到的组件,它将一个图片显示到屏幕上. 在UI xml定义一个ImageView如下: public void onCreate(Bundle savedI ...

  6. 设置umask

    umask 002 例子:umask为003,建立的文件与目录权限是什么? umask为003,所有去掉的属性为-------wx,因此 文件  -rw-rw-r-- 目录 drwxrwxr--

  7. 国家气象局提供的天气预报接口(完整Json接口)

    国家气象局提供的天气预报接口主要有三个,分别是:http://www.weather.com.cn/data/sk/101010100.htmlhttp://www.weather.com.cn/da ...

  8. Asp.Net Core 入门(九)—— 环境变量 TagHelper

    我们在之前讲Program.cs文件做了什么的时候,提到启动CreaeDefaultBuilder会获取环境变量来做一些判断之类的操作.那么我们的Taghelper也可以使用“ASPNETCORE_E ...

  9. PHP必知必会

    MQ(消息队列) 消息队列主要用于以下场景: 1. 上传图片,用户需要迅速反馈,把上传图片的后续操作交给consumer 2. A用户对B用户发消息 3. 日志记录,APP发生的任何警告错误日志都要被 ...

  10. 【二分】bestcoder p1m2

    模型的转化和二分check的细节挺不错的 Problem Description 度度熊很喜欢数组!! 我们称一个整数数组为稳定的,若且唯若其同时符合以下两个条件: 数组里面的元素都是非负整数. 数组 ...