LeetCode刷题Java版040.组合总和 II
作者:沉默王二
发布时间:2022-09-13T11:30:05.956+0800
040.组合总和 II
题意
给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用 一次 。
注意:解集不能包含重复的组合。
难度
中等
示例
输入: candidates = [10,1,2,7,6,1,5], target = 8,
[[1,1,6],[1,2,5],[1,7],[2,6]]
分析
本题跟 039.组合总和 最大的差别就在于——同一个数字不能被重复选择,但是candidates中可能会存在有重复的数字。
因为candidates中的先后顺序并不会影响答案,而且如果有重复元素的话放在一起也会更有利于解题,所以,我们先把candidates排序一遍。
排序之后就可以看出一些端倪了。
如果有数字出现两次或两次以上,那么在我们递归到第step步的时候,需要从begin-(candidates.length - 1)中选择一个元素,然后继续向下递归选择下一个元素。
但是,如果现在要选的元素——也就是candidates[i],和candidates[i - 1]一样大概怎么办呢?
直接选择,然后递归下去?
看下图,这是一棵简单的由递归搜索形成的部分解答树:
我们发现,答案重复出现了。
出现的原因,就是因为我们在选择第三个数字的时候,有[2,2]的存在,导致第三个数字重复了,所以,如果一个数字跟上一个一样,这个数字是可以直接跳过的。
那为什么之前的1可以被连续选择呢?
因为我们在选择第二个1的时候,已经到了 第二步 ,是选择了第一个1的后续状态,而并非选择第一个1的平行状态。而第二个2的选择,则是和第一个2处于平行状态,也就是递归的同一层。
所以,这道题便迎刃而解了。我们只需要先排序,然后在枚举的时候,过滤掉相同的,然后找寻下一个即可。
class Solution {
private void DFS(List
表现也很不错
时间复杂度的上界是:
因为每个数字都有选或者不选两个状态,还有最后将这些合法答案加入总方案中的时间,所以是,再加上一开始的排序操作,总的时间复杂度的上界是上述的式子,但是,因为可以过滤掉总和超过target的部分,以及重复选择同个数字的部分,所以实际上的运行时间肯定是远远低于上限的。
总结
本题仍然是一道递归搜索的题目,这类题目的思路通常都能非常快的想出来,因为和我们平时的思考过程非常类似,重点在于如何优化搜索和枚举的时间,如果能细心分析,找到题目中的特殊性质,就能把这类题目解决。
力扣链接:https://leetcode.cn/problems/combination-sum-ii/
一步一个脚印
不积跬步无以至千里,不积小流无以成江海。LeetCode - 100天从算法小白到卷王正式启动了,我们计划周一到周五至少每天更新一篇,周六周日更新一篇,目标 300 道 LeetCode 经典题。
PDF 版本目前只针对**二哥编程星球 的球友开放,如果你也想一起打卡学习算法的话,戳链接 **加入我们吧。
一个人可以走得很快,但一群人才能走得更远。二哥编程星球 (目前已有 780 多名球友加入)里面的每个球友都非常的友善,除了鼓励你,还会给你提出合理的建议,一起冲!
040.组合总和 II
题意
给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用 一次 。
注意:解集不能包含重复的组合。
难度
中等
示例
输入: candidates = [10,1,2,7,6,1,5], target = 8,
[[1,1,6],[1,2,5],[1,7],[2,6]]
分析
本题跟 039.组合总和 最大的差别就在于——同一个数字不能被重复选择,但是candidates中可能会存在有重复的数字。
因为candidates中的先后顺序并不会影响答案,而且如果有重复元素的话放在一起也会更有利于解题,所以,我们先把candidates排序一遍。
排序之后就可以看出一些端倪了。
如果有数字出现两次或两次以上,那么在我们递归到第step步的时候,需要从begin-(candidates.length - 1)中选择一个元素,然后继续向下递归选择下一个元素。
但是,如果现在要选的元素——也就是candidates[i],和candidates[i - 1]一样大概怎么办呢?
直接选择,然后递归下去?
看下图,这是一棵简单的由递归搜索形成的部分解答树:
我们发现,答案重复出现了。
出现的原因,就是因为我们在选择第三个数字的时候,有[2,2]的存在,导致第三个数字重复了,所以,如果一个数字跟上一个一样,这个数字是可以直接跳过的。
那为什么之前的1可以被连续选择呢?
因为我们在选择第二个1的时候,已经到了 第二步 ,是选择了第一个1的后续状态,而并非选择第一个1的平行状态。而第二个2的选择,则是和第一个2处于平行状态,也就是递归的同一层。
所以,这道题便迎刃而解了。我们只需要先排序,然后在枚举的时候,过滤掉相同的,然后找寻下一个即可。
class Solution {
private void DFS(List
表现也很不错
时间复杂度的上界是:
因为每个数字都有选或者不选两个状态,还有最后将这些合法答案加入总方案中的时间,所以是,再加上一开始的排序操作,总的时间复杂度的上界是上述的式子,但是,因为可以过滤掉总和超过target的部分,以及重复选择同个数字的部分,所以实际上的运行时间肯定是远远低于上限的。
总结
本题仍然是一道递归搜索的题目,这类题目的思路通常都能非常快的想出来,因为和我们平时的思考过程非常类似,重点在于如何优化搜索和枚举的时间,如果能细心分析,找到题目中的特殊性质,就能把这类题目解决。
力扣链接:https://leetcode.cn/problems/combination-sum-ii/
一步一个脚印
不积跬步无以至千里,不积小流无以成江海。LeetCode - 100天从算法小白到卷王正式启动了,我们计划周一到周五至少每天更新一篇,周六周日更新一篇,目标 300 道 LeetCode 经典题。
PDF 版本目前只针对**二哥编程星球 的球友开放,如果你也想一起打卡学习算法的话,戳链接 **加入我们吧。
一个人可以走得很快,但一群人才能走得更远。二哥编程星球 (目前已有 780 多名球友加入)里面的每个球友都非常的友善,除了鼓励你,还会给你提出合理的建议,一起冲!
040.组合总和 II
题意
给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用 一次 。
注意:解集不能包含重复的组合。
难度
中等
示例
输入: candidates = [10,1,2,7,6,1,5], target = 8,
[[1,1,6],[1,2,5],[1,7],[2,6]]
分析
本题跟 039.组合总和 最大的差别就在于——同一个数字不能被重复选择,但是candidates中可能会存在有重复的数字。
因为candidates中的先后顺序并不会影响答案,而且如果有重复元素的话放在一起也会更有利于解题,所以,我们先把candidates排序一遍。
排序之后就可以看出一些端倪了。
如果有数字出现两次或两次以上,那么在我们递归到第step步的时候,需要从begin-(candidates.length - 1)中选择一个元素,然后继续向下递归选择下一个元素。
但是,如果现在要选的元素——也就是candidates[i],和candidates[i - 1]一样大概怎么办呢?
直接选择,然后递归下去?
看下图,这是一棵简单的由递归搜索形成的部分解答树:
我们发现,答案重复出现了。
出现的原因,就是因为我们在选择第三个数字的时候,有[2,2]的存在,导致第三个数字重复了,所以,如果一个数字跟上一个一样,这个数字是可以直接跳过的。
那为什么之前的1可以被连续选择呢?
因为我们在选择第二个1的时候,已经到了 第二步 ,是选择了第一个1的后续状态,而并非选择第一个1的平行状态。而第二个2的选择,则是和第一个2处于平行状态,也就是递归的同一层。
所以,这道题便迎刃而解了。我们只需要先排序,然后在枚举的时候,过滤掉相同的,然后找寻下一个即可。
class Solution {
private void DFS(List
表现也很不错
时间复杂度的上界是:
因为每个数字都有选或者不选两个状态,还有最后将这些合法答案加入总方案中的时间,所以是,再加上一开始的排序操作,总的时间复杂度的上界是上述的式子,但是,因为可以过滤掉总和超过target的部分,以及重复选择同个数字的部分,所以实际上的运行时间肯定是远远低于上限的。
总结
本题仍然是一道递归搜索的题目,这类题目的思路通常都能非常快的想出来,因为和我们平时的思考过程非常类似,重点在于如何优化搜索和枚举的时间,如果能细心分析,找到题目中的特殊性质,就能把这类题目解决。
力扣链接:https://leetcode.cn/problems/combination-sum-ii/
一步一个脚印
不积跬步无以至千里,不积小流无以成江海。LeetCode - 100天从算法小白到卷王正式启动了,我们计划周一到周五至少每天更新一篇,周六周日更新一篇,目标 300 道 LeetCode 经典题。
PDF 版本目前只针对**二哥编程星球 的球友开放,如果你也想一起打卡学习算法的话,戳链接 **加入我们吧。
一个人可以走得很快,但一群人才能走得更远。二哥编程星球 (目前已有 780 多名球友加入)里面的每个球友都非常的友善,除了鼓励你,还会给你提出合理的建议,一起冲!
知识星球
扫码加入星球
查看更多优质内容
https://wx.zsxq.com/mweb/views/joingroup/join_group.html?group_id=15522885221412