这道题是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. 除虫记——有关WindowsAPI文件查找函数的一次压力测试

    作者:朱金灿 来源:http://blog.csdn.net/clever101 这里说的除虫是指排除bug的意思.今天排除了一个有意思的bug,其中的场景大致是这样的:现在你要统计一个文件夹下非隐藏 ...

  2. DVWA之Brute Force教程

    ---恢复内容开始--- Brute Force暴力破解模块,是指黑客密码字典,使用穷举的方法猜出用户的口令,是一种广泛的攻击手法. LOW low级别的漏洞利用过程 1.使用burp suite工具 ...

  3. IOS之网络状态设和NSUserDefaults的synchronize

    #pragma mark - check net status int apiCheckNetStatus() { Reachability *reachNet = [Reachability rea ...

  4. VC操作WORD文档总结

    一.写在开头 最近研究word文档的解析技术,我本身是VC的忠实用户,看到C#里面操作WORD这么舒服,同时也看到单位有一些需求,就想尝试一下,结果没想到里面的技术点真不少,同时网络上的共享资料很多, ...

  5. 51nod 1283 最小周长

    一个矩形的面积为S,已知该矩形的边长都是整数,求所有满足条件的矩形中,周长的最小值.例如:S = 24,那么有{1 24} {2 12} {3 8} {4 6}这4种矩形,其中{4 6}的周长最小,为 ...

  6. Google Colab免费GPU使用教程(一)

    一.前言 现在你可以开发Deep Learning Applications在Google Colaboratory,它自带免费的Tesla K80 GPU.重点是免费.免费!(国内可能需要tz) 这 ...

  7. 关于POST的请求的问题的汇总

    1)404 解决方式:检查路径,路由问题 2)500 解决方式:1)首先检查代码 2)检查是否是参数未接收到 3)检查是否Content-Type类型导致的参数未收到 4)区分body-raw跟bod ...

  8. javase(3)_二叉树

    // 1.求二叉树中的节点个数 // 2.求二叉树的深度 // 3.前序遍历,中序遍历,后序遍历 // 4.分层遍历二叉树(按层次从上往下,从左往右) // 5.将二叉查找树变为有序的双向链表 // ...

  9. baidumap demo(一)

    覆盖物概述 地图上自定义的标注点和覆盖物我们统称为地图覆盖物.您可以通过定制BMKAnnotation和BMKOverlay来添加对应的标注点和覆盖物.地图覆盖物的设计遵循数据与View分离的原则,B ...

  10. x220 OS X 10.10.4安装

    变色龙安装过程: 1.使用磁盘助手将按照盘写入独立的磁盘分区(AF格式,就是Apple的HPS格式): 2.安装启动时,用-v -f -x参数,分别为显示信息.重新build系统驱动.安全模式: 3. ...