【Subsets II】cpp
题目:
Given a collection of integers that might contain duplicates, nums, return all possible subsets.
Note:
- Elements in a subset must be in non-descending order.
- The solution set must not contain duplicate subsets.
For example,
If nums = [1,2,2]
, a solution is:
[ [2], [1], [1,2,2], [2,2], [1,2], [] ]
代码:
class Solution { public: vector<vector<int>> subsetsWithDup(vector<int>& nums) { std::sort(nums.begin(), nums.end()); vector<vector<int> > ret; vector<int> tmp; Solution::dfs(ret, nums, 0, tmp); return ret; } static void dfs(vector<vector<int> >& ret, vector<int>& nums, int index, vector<int>& tmp ) { if ( index==nums.size() ) { ret.push_back(tmp); return; } tmp.push_back(nums[index]); Solution::dfs(ret, nums, index+1, tmp); tmp.pop_back(); if ( !(tmp.size()>=1 && tmp.back()==nums[index]) ) { Solution::dfs(ret, nums, index+1, tmp); } } };
tips:
大体思路与Subsets类似(http://www.cnblogs.com/xbf9xbf/p/4516802.html)
经过画图推演:dfs向左边走的条件不变;再向右边走时,如果当前节点的最后一个元素与即将要加入的新元素相同,则不往右边走了。因为再往右边走,右边肯定包含左边的重复子集了。
===================================
再补充一个增量构造法的迭代解法,代码如下:
class Solution { public: vector<vector<int>> subsetsWithDup(vector<int>& nums) { std::sort(nums.begin(), nums.end()); vector<vector<int> > ret; vector<int> none; ret.push_back(none); int pureNew = 0; for ( size_t i = 0; i < nums.size(); ++i ) { vector<vector<int> > tmp = ret; size_t begin = 0; if ( i>=1 && nums[i]==nums[i-1] ) { begin = ret.size()-pureNew; } for ( size_t j = begin; j < tmp.size(); ++j ) { tmp[j].push_back(nums[i]); ret.push_back(tmp[j]); } pureNew = ret.size() - tmp.size(); } return ret; } };
tips:
增加新元素前,判断nums[i]==nums[i-1]的条件是否成立;如果成立,则增量应该只作用于上一轮新增加的子集上,这样保证没有重复的;这个思路也很简洁。
学习了几个blog的思路:
http://bangbingsyb.blogspot.sg/2014/11/leetcode-subsets-i-ii.html
http://www.cnblogs.com/TenosDoIt/p/3451902.html
http://www.cnblogs.com/yuzhangcmu/p/4211815.html
完毕。
============================================
第二次过这道题,只用dfs的写法。再次画画图,理解一下。
class Solution { public: vector<vector<int> > subsetsWithDup(vector<int>& nums) { sort(nums.begin(), nums.end()); vector<vector<int> > ret; vector<int> tmp; Solution::dfs(ret, nums, 0, tmp); return ret; } static void dfs( vector<vector<int> >& ret, vector<int>& nums, int index, vector<int>& tmp) { if ( index==nums.size() ) { ret.push_back(tmp); return; } tmp.push_back(nums[index]); Solution::dfs(ret, nums, index+1, tmp); tmp.pop_back(); if ( !(tmp.size()>0 && tmp.back()==nums[index]) ) { Solution::dfs(ret, nums, index+1, tmp); } } };
用深搜的好处就体现出来了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?