【LeetCode从零单刷】Combinations & Combination Sum 系列
2015-10-31 22:35
555 查看
题目:
Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
For example,
If n = 4 and k = 2, a solution is:
解答:
排列组合类型的问题,一般都是利用回溯法。关于回溯法的要点,在这篇文章里面说的已经很清楚了:传送门
每次只递归一步,绝不多一步。这个和递归法是相同的道理;
只有最底层负责存入结果,存入一个脱离于函数的全局内存;
层与层之间,不再传递数据(因为回溯的答案不止一个,每层处理去重没必要,交给最底层存入)。但是每层必须有 return 返回上层,否则函数无法终止),return 一个空值
另外还有三道类似的题目:Combination Sum,Combination Sum II,Combination
Sum III
套路都是一样的。不过需要先排序,第一题可以选择重复元素,这样回溯的起点还是当前起点;第二题不可以选择重复元素,回溯起点就是当前起点下一个;第三题还有多出来的位数限制。
Combination Sum I:
class Solution {
public:
vector<vector<int>> ans;
void combination(vector<int> cur, int target, vector<int> candidates, int start)
{
int cursize = cur.size();
int size = candidates.size();
int cursum = 0;
for(int i=0; i<cursize; i++) cursum += cur[i];
for(int i = start; i < size; i++)
{
vector<int> tmp = cur;
if(cursum + candidates[i] == target)
{
tmp.push_back(candidates[i]);
ans.push_back(tmp);
break;
}
else if(cursum + candidates[i] < target)
{
tmp.push_back(candidates[i]);
combination(tmp, target, candidates, i);
}
else break;
}
return;
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<int> cur;
sort(candidates.begin(), candidates.end());
combination(cur, target, candidates, 0);
return ans;
}
};
Combination Sum II:
Combination Sum III:
Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
For example,
If n = 4 and k = 2, a solution is:
[ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
解答:
排列组合类型的问题,一般都是利用回溯法。关于回溯法的要点,在这篇文章里面说的已经很清楚了:传送门
每次只递归一步,绝不多一步。这个和递归法是相同的道理;
只有最底层负责存入结果,存入一个脱离于函数的全局内存;
层与层之间,不再传递数据(因为回溯的答案不止一个,每层处理去重没必要,交给最底层存入)。但是每层必须有 return 返回上层,否则函数无法终止),return 一个空值
class Solution { public: vector<vector<int>> ans; void insert(int start, int end, int bit, vector<int> cur) { if(bit == 0) { ans.push_back(cur); return; } for(int i=start; i<= end - bit + 1; i++) { vector<int> tmp(cur); tmp.push_back(i); insert(i+1, end, bit-1, tmp); } return; } vector<vector<int>> combine(int n, int k) { vector<int> tmp; insert(1, n, k, tmp); return ans; } };
另外还有三道类似的题目:Combination Sum,Combination Sum II,Combination
Sum III
套路都是一样的。不过需要先排序,第一题可以选择重复元素,这样回溯的起点还是当前起点;第二题不可以选择重复元素,回溯起点就是当前起点下一个;第三题还有多出来的位数限制。
Combination Sum I:
class Solution {
public:
vector<vector<int>> ans;
void combination(vector<int> cur, int target, vector<int> candidates, int start)
{
int cursize = cur.size();
int size = candidates.size();
int cursum = 0;
for(int i=0; i<cursize; i++) cursum += cur[i];
for(int i = start; i < size; i++)
{
vector<int> tmp = cur;
if(cursum + candidates[i] == target)
{
tmp.push_back(candidates[i]);
ans.push_back(tmp);
break;
}
else if(cursum + candidates[i] < target)
{
tmp.push_back(candidates[i]);
combination(tmp, target, candidates, i);
}
else break;
}
return;
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<int> cur;
sort(candidates.begin(), candidates.end());
combination(cur, target, candidates, 0);
return ans;
}
};
Combination Sum II:
class Solution { public: set<vector<int>> tmpans; void combination(vector<int> cur, int target, vector<int> candidates, int start) { int cursize = cur.size(); int size = candidates.size(); int cursum = 0; for(int i=0; i<cursize; i++) cursum += cur[i]; for(int i = start; i < size; i++) { vector<int> tmp = cur; if(cursum + candidates[i] == target) { tmp.push_back(candidates[i]); tmpans.insert(tmp); break; } else if(cursum + candidates[i] < target) { tmp.push_back(candidates[i]); combination(tmp, target, candidates, i+1); } else break; } return; } vector<vector<int>> combinationSum2(vector<int>& candidates, int target) { vector<int> cur; sort(candidates.begin(), candidates.end()); combination(cur, target, candidates, 0); vector<vector<int>> ans(tmpans.begin(), tmpans.end()); return ans; } };
Combination Sum III:
class Solution { public: vector<vector<int>> ans; void combination(int k, int n, vector<int> cur, int start, int bit) { if(k < bit) return; int cursize = cur.size(); int cursum = 0; for(int i=0; i<cursize; i++) cursum += cur[i]; vector<int> tmp; for(int i = start + 1; i <= 9; i++) { if (cursum + i == n && k == bit + 1) { tmp = cur; tmp.push_back(i); ans.push_back(tmp); break; } else if (cursum + i < n && k > bit) { tmp = cur; tmp.push_back(i); combination(k, n, tmp, i, bit + 1); } else break; } return; } vector<vector<int>> combinationSum3(int k, int n) { vector<int> cur; combination(k, n, cur, 0, 0); return ans; } };
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性
- C++ Custom Control控件向父窗体发送对应的消息