前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >leetcode 40. 组合总和 II---回溯篇3

leetcode 40. 组合总和 II---回溯篇3

作者头像
大忽悠爱学习
发布2021-11-15 11:00:26
1840
发布2021-11-15 11:00:26
举报
文章被收录于专栏:c++与qt学习
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

组合总和||题解集合


回溯法

解题思路:

一句话题解:按顺序搜索,设置合理的变量,在搜索的过程中判断是否会出现重复集结果。重点理解对输入数组排序的作用

与第 39 题(组合之和)的差别

这道题与上一问的区别在于:

  • 第 39 题:candidates 中的数字可以无限制重复被选取;
  • 第 40 题:candidates 中的每个数字在每个组合中只能使用一次。

相同点是:相同数字列表的不同排列视为一个结果。

如何去掉重复的集合(重点)

为了使得解集不包含重复的组合。有以下 22 种方案:

  • 使用 哈希表 天然的去重功能,但是编码相对复杂;
  • 使用和第 39 题和第 15 题(三数之和)类似的思路:不重复就需要按 顺序 搜索, 在搜索的过程中检测分支是否会出现重复结果 。注意:这里的顺序不仅仅指数组 candidates 有序,还指按照一定顺序搜索结果。
在这里插入图片描述
在这里插入图片描述

由第 39 题我们知道,数组 candidates 有序,也是 深度优先遍历 过程中实现「剪枝」的前提。

将数组先排序的思路来自于这个问题去掉一个数组中重复的元素,看上图可知,是去掉后一个重复数字1

关键代码:if (i>index&&candidates[i] == candidates[i - 1]) continue;

i>index可以看上图,多叉树第一层可选数字有1,1,2.

显然选择第一个数字1的时候不需要考虑去重的问题,因此需要写i>index

如果不写,那么会产生溢出,因此一开始i=0而i-1=-1

代码:

代码语言:javascript
复制
class Solution {
	vector<vector<int>> ret;
public:
	vector<vector<int>> combinationSum2(vector<int>& candidates, int target)
	{
		if (accumulate(candidates.begin(), candidates.end(), 0) < target) return ret;
		vector<int> num;
		sort(candidates.begin(), candidates.end());
		backTrace(candidates, target,num,0);
		return ret;
	}
	void backTrace(vector<int>& candidates, int target,vector<int>& num,int index)
	{
		if (target == 0)
		{
			ret.push_back(num);
			return;
		}
		for (int i =index; i < candidates.size() && target - candidates[i] >= 0; i++)
		{
			if (i>index&&candidates[i] == candidates[i - 1]) continue;
			num.push_back(candidates[i]);
			backTrace(candidates, target - candidates[i], num, i+1);
			num.pop_back();
		}
	}
};
在这里插入图片描述
在这里插入图片描述

哈希法去重

思路:

先对数组进行排序,然后使用set容器存储所有结果,当出现相同结果的时候,set容器会插入失败

但是注意一定要先对数组进行排序,如果不排序:[1,2,1]和[1,1,2]这样两个数组,set容器会认为两种不相等,排序后,两个数组就会都变成[1,1,2],这样插入第一个[1,1,2]后,遇到第二个[1,1,2]就会插入失败

代码:

代码语言:javascript
复制
class Solution {
	set<vector<int>> ret;
public:
	vector<vector<int>> combinationSum2(vector<int>& candidates, int target)
	{
		if (accumulate(candidates.begin(), candidates.end(), 0) < target) return vector<vector<int>>();
		vector<int> num;
		sort(candidates.begin(), candidates.end());
		backTrace(candidates, target,0,num);
		vector<vector<int>> r;
			return vector<vector<int>>(ret.begin(),ret.end());
	}
	void backTrace(vector<int>& candidates, int target,int index,vector<int>& num)
	{
		if (target == 0)
		{
			ret.insert(num);
			return;
		}
		for (int i = index; i < candidates.size() && target - candidates[i] >= 0; i++)
		{
			num.push_back(candidates[i]);
			backTrace(candidates, target - candidates[i], i + 1, num);
			num.pop_back();
		}
	}
};
在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/05/28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 组合总和||题解集合
  • 回溯法
  • 哈希法去重
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档