LeetCode算法题——Combination Sum I & II
来源:互联网 发布:php采集 编辑:程序博客网 时间:2024/06/14 15:15
这两题因为题设相近,且解题方法基本一致,因此集中讨论。
问题概述
I:
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]]
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]]
分析
两道题目的题设中基本都是“给定数组并利用数组元素查找满足和为目标数的组合”。此类问题,直观的想法就是运用DFS的思想,用近似人的思考方式,将原始数组进行排序以后从小到大不断尝试组合,判断是否是否满足题意。而要做到这一点,最直接的方法就是运用递归。
观察发现,两道题目的区别仅仅为是否限制数组元素使用次数,因此实际上他们的大致解体思路是一样的。下面先给出问题I的代码,部分解释说明已附在代码中:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) { vector<vector<int>> result; // 存储满足题意组合的数组 vector<int> temp; // 临时数组,存储当前的组合 std::sort(candidates.begin(), candidates.end()); // 需要先对原始数组进行排序 getsum(candidates, target, result, temp, 0); return result; }// 递归函数,处理当前的数组void getsum(vector<int>& candidates, int target, vector<vector<int> > &result, vector<int>& temp, int pos) { if (!target) { // 当前尝试的组合满足题意,加入最终结果 result.push_back(temp); return; } for (int i = pos; i < candidates.size() && target >= candidates[i]; i++) { temp.push_back(candidates[i]); // 向组合中加入新的数 // 递归调用,可以发现新的目标数参数发生了相应改变;而由于每一个元素使用次数没有限制,因此 // pos参数仍然为i,即上一次遍历至的位置 getsum(candidates, (target-candidates[i]), result, temp, i); temp.pop_back(); // 当前的组合数大于目标数,因此需要将组合最大的数弹出 }}
题目II的大致解体思路与之类似,只需要针对元素使用限制这一条件进行若干修改:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) { vector<vector<int>> result; vector<int> temp; std::sort(candidates.begin(), candidates.end()); getsum(candidates, target, result, temp, 0); return result; } void getsum(vector<int>& candidates, int target, vector<vector<int> > &result,vector<int>& temp, int pos) { if (!target) { result.push_back(temp); return; } for (int i = pos; i < candidates.size() && target >= candidates[i]; i++) { temp.push_back(candidates[i]); // 由于使用过的元素不能再使用,因此pos参数变为i+1,即需要从上一次遍历到的下一个元素开始递归 getsum(candidates, (target-candidates[i]), result, temp, i+1); temp.pop_back(); // 需要跳过重复的组合 while (i+1 < candidates.size() && candidates[i] == candidates[i+1]) i++; }}
总结
- 解决此类组合数问题,往往需要运用DFS的思想,具体实现则可以借鉴递归
- 灵活的调整递归函数的参数,要紧密结合题目的具体要求,例如是否限制元素的使用次数等等。
- LeetCode算法题——Combination Sum I & II
- 【leetcode】Array——Combination Sum I/II/III
- Leetcode Combination Sum I & II
- 【LeetCode】Combination Sum I && II
- leetcode Combination Sum I &II
- LeetCode - Combination Sum I && II
- Combination Sum I/II - Leetcode
- leetcode:Combination Sum(I,II)
- LeetCode | Combination Sum I,II
- leetCode刷题归纳-backtracking(39. Combination Sum I && II)
- LeetCode题解:Combination Sum I and II
- LeetCode Solutions : Combination Sum I & II
- 【LeetCode】Combination Sum I & II 解题报告
- [leetcode] 39& 40 Combination Sum I& II
- [LeetCode 39&40] Combination Sum I & II
- [leetcode题后感]combination sum i,ii
- LeetCode 39/40. Combination Sum i, ii
- leetcode Combination Sum I/II/III/IV
- gradle 在Android构建过程中基本实现解析(陆续)
- WebRTC(AppRTC) 本地部署
- mysql sql demo
- HDU 3579 Hello Kiki(拓展中国剩余定理)
- ByteBuf转byte[]
- LeetCode算法题——Combination Sum I & II
- 联网,网络判断的实现方式
- atom 不同窗口打开同一文件
- .net/C# 进程和线程
- 出现 warning: Clock skew detected. Your build may be incomplete.这样的警告
- 为何网站需要静态化
- 我的python学习笔记、从文件中读取数据
- 进行网站开发是如何选择域名
- Qt 设置全局字体