[LeetCode OJ]Combination Sum I && II

7 篇文章 0 订阅
2 篇文章 0 订阅

【问题描述】

Given a set of candidate numbers (C(without duplicates) 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]
]
问题来源:Combination Sum


【解题分析】

给出一个数据集和一个目标数字,找出数据集中所有满足和为目标数字的子集合,数据集中的数字可重复使用,但最后满足条件的集合不得重复。
采用深度优先算法DFS:
就以题中的例子讲解一下算法,2->2->2->2,发现8>7,遍历上一节点的其他子节点,2->2->2->3,9>7,.....,直到2->2->2->7,返回到上一节点,开始2->2->3,......,如此,最后到6->6,6->7,7。

【源代码】

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> result;
        vector<int> mid_result;
        DFS(result, mid_result, candidates, 0, 0, target);
        return result;
    }
private:
    void DFS(vector<vector<int>>& result, vector<int>& mid_result, vector<int> candidates, int i, int sum, int target) {
    	if (sum == target) {
    		result.push_back(mid_result);
    		return ;
    	} else if (sum > target){
    		return ;
    	} else {
    		for (int j = i; j < candidates.size(); j++) {
    			mid_result.push_back(candidates[j]);
    			DFS(result, mid_result, candidates, j, sum + candidates[j], target);
    			mid_result.pop_back(); /*该节点已被遍历,且该节点已无子节点需要遍历,将其取出*/
    		}
    	}
    }
};

Combination Sum II

【问题描述】

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

Each number in C may only be used once in the combination.

Note:

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

For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8
A solution set is: 

[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]
问题来源:Combination Sum II


【解题分析】

这题和上面那题非常相似,只不过多加了条件,那就是集合内的元素不得重复使用,而且有个不同于前一题的条件,那就是集合内的元素可能会重复。
基于以上的条件,我们仍采用上一题的思路,只不过这次我们不会连续重复遍历一个节点。
for (int i = start; i < candidates.size(); i++) {
	mid_result.push_back(candidates[i]);
    	DFS(candidates, i + 1, sum + candidates[i], target, mid_result, result);
    	mid_result.pop_back();
}
区别于上一题:
for (int j = i; j < candidates.size(); j++) {
    	mid_result.push_back(candidates[j]);
    	DFS(result, mid_result, candidates, j, sum + candidates[j], target);
    	mid_result.pop_back(); /*该节点已被遍历,且该节点已无子节点需要遍历,将其取出*/
}
而且由于集合内的元素可能会重复,那么得到的结果集合内可能会有相同的集合。我们需要去掉重复集合。
sort(result.begin(), result.end());
result.erase(unique(result.begin(), result.end()), result.end());

【源代码】

class Solution {
public:
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        vector<vector<int>> result;
        vector<int> mid_result;
        int sum = 0;
        sort(candidates.begin(), candidates.end());
        DFS(candidates, 0, 0, target, mid_result, result);
        sort(result.begin(), result.end());
        result.erase(unique(result.begin(), result.end()), result.end());
        return result;
    }
private:
    void DFS(vector<int> candidates, int start, int sum, int target, vector<int>& mid_result, vector<vector<int>>& result) {
    	if (sum == target) {
    		result.push_back(mid_result);
    	} else if (sum > target) {
    		return ;
    	} else {
    		for (int i = start; i < candidates.size(); i++) {
    			mid_result.push_back(candidates[i]);
    			DFS(candidates, i + 1, sum + candidates[i], target, mid_result, result);
    			mid_result.pop_back();
    		}
    	}
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值