39. Combination Sum

Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

The same repeated number may be chosen from C unlimited number of times.

Note:

  • All numbers (including target) will be positive integers.
  • The solution set must not contain duplicate combinations.

For example, given candidate set [2, 3, 6, 7] and target 7
A solution set is: 

[
  [7],
  [2, 2, 3]
]


  题目的意思是,给出一个目标数target(T),在candidates数组(C)中找到和为T的所有可能的组合,需要注意的一点是,数组中的数字可以重复选择。

  这道题可以用回溯的方法解决,若从后往前进行遍历,对于数组中的每个数candidates[i],有如下三种情况:

  ① candidates[i] < target。则将candidates[i]选入com中,然后递归调用backtrack1函数,注意此时target要减去candidates[i],形成一个与原问题类似的子问题,即从candidates[0]到candidates[i]中找到和为target - candidates[i]的所有可能的组合。

  ② candidates[i] = target。说明找到一个可能的组合,将com选入res中。

  ③ candidates[i] > target。这种情况就不必继续探讨了,直接continue。

  当然也可以从前往后遍历(backtrack2函数),只需在backtrack1函数的基础上稍微修改即可,因此这两个函数实质上并没有什么区别,对同一个样例来说,运行过程中两个函数被调用的次数一模一样。但有趣的是,用两种函数去提交,得到的Run time相差还是挺大的,backtrack1用了29ms,而backtrack2用了42ms,不清楚为什么两个时间复杂度一样的函数的Run time相差这么大。

  至于算法的时间复杂度,跟样例有很大的关系,难以计算。

  代码如下:

class Solution {
public:
	void backtrack1(vector<int> com, int right, int target) {
		for (int i = right; i >= 0; i--) {
			if (candidates[i] > target) continue;
			else if (candidates[i] == target) {
				vector<int> tmp = com;
				tmp.push_back(candidates[i]);
				res.push_back(tmp);
			}
			else {
				vector<int> tmp = com;
				tmp.push_back(candidates[i]);
				backtrack1(tmp, i, target - candidates[i]);
			}
		}
	}
	void backtrack2(vector<int> com, int left, int target) {
		for (int i = left; i < candidates.size(); i++) {
			if (candidates[i] > target) break;
			else if (candidates[i] == target) {
				vector<int> tmp = com;
				tmp.push_back(candidates[i]);
				res.push_back(tmp);
			}
			else {
				vector<int> tmp = com;
				tmp.push_back(candidates[i]);
				backtrack2(tmp, i, target - candidates[i]);
			}
		}
	}
	vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
		sort(candidates.begin(), candidates.end());
		this->candidates = candidates;
		//backtrack1(vector<int>(0), candidates.size() - 1, target);
		backtrack2(vector<int>(0), 0, target);
		return res;
	}
private:
	vector<int> candidates;
	vector<vector<int>> res;
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值