标签:tmp Subsets nums int back ret II vector LeetCode
目录
题目链接
注意点
- 有重复的数字
- 数组可能是无序的,要先排序
解法
解法一:递归,只需要在Subsets中递归写法的基础上多加一句if(find(ret.begin(),ret.end(),tmp) == ret.end()) ret.push_back(tmp);
j即可,因为已经排序了,所以加进去的如果已经存在就说明是重复的。
class Solution {
public:
typedef vector<int> v;
void recursion(int start,v nums,v tmp, vector<v>& ret)
{
if(find(ret.begin(),ret.end(),tmp) == ret.end()) ret.push_back(tmp);
int n = nums.size();
for(int i = start;i < n;i++)
{
tmp.push_back(nums[i]);
recursion(i+1,nums,tmp,ret);
tmp.pop_back();
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(),nums.end());
vector<vector<int>> ret;
v tmp;
recursion(0,nums,tmp,ret);
return ret;
}
};
解法二:递归。只需要在Subsets中递归写法的基础上多加一句while(i+1 < n && nums[i] == nums[i+1]) i++;
即可,这句话的作用就是把下图中树结点为X的剪枝。
[]
/ \
/ \
/ \
[1] []
/ \ / \
/ \ / \
[1 2] [1] [2] []
/ \ / \ / \ / \
[1 2 2] [1 2] X [1] [2 2] [2] X []
class Solution {
public:
typedef vector<int> v;
void recursion(int start,v nums,v tmp, vector<v>& ret)
{
ret.push_back(tmp);
int n = nums.size();
for(int i = start;i < n;i++)
{
tmp.push_back(nums[i]);
recursion(i+1,nums,tmp,ret);
tmp.pop_back();
while(i+1 < n && nums[i] == nums[i+1]) i++;
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(),nums.end());
vector<vector<int>> ret;
v tmp;
recursion(0,nums,tmp,ret);
return ret;
}
};
解法三:非递归。在Subsets中非递归写法的基础上进行修改,如果当前数字和上一次循环的数字一样,那么就只能在上一次循环产生的集合后面追加当前数字,而不能在所有集合后面追加
class Solution {
public:
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
if(nums.empty()) return {};
sort(nums.begin(),nums.end());
vector<vector<int>> ret(1);
int i,j,n = nums.size(),last = nums[0],lastSize = 1;
for(i = 0;i < n;i++)
{
if(last != nums[i])
{
last = nums[i];
lastSize = ret.size();
}
int m = ret.size();
for(j = m-lastSize;j < m;j++)
{
ret.push_back(ret[j]);
ret.back().push_back(nums[i]);
}
}
return ret;
}
};
小结
标签:tmp,Subsets,nums,int,back,ret,II,vector,LeetCode 来源: https://www.cnblogs.com/multhree/p/10523567.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。