您的位置:首页 > 其它

【leetcode】90. Subsets II

2016-01-24 10:31 323 查看
总结一下,leetcode Subsets II ,题目的意思是得到一个含有重复元素的集合的所有子集。

下面分别给出3种解法。

1. dfs. 该解法16ms beats 17.33%
of cpp submissions.

class Solution {
public:
void dfs(int idx, vector<int>& tmp, vector<vector<int>>& ans, vector<int>& nums){
ans.push_back(tmp);

// for循环的关键是,对于下一个与当前元素相同的元素,都需要跳过
// 也就是 1, 1, 1, 2, 2, 3, 4, 4. 最终这个for循环只能遍历1, 2, 3, 4.
for(int i = idx; i < nums.size(); ++ i) {
if(i && i > idx && nums[i] == nums[i-1]) continue;
tmp.push_back(nums[i]);
dfs(i+1, tmp, ans, nums);
tmp.pop_back();
}

}

vector<vector<int>> subsetsWithDup(vector<int>& nums) {
vector<vector<int>> ans;
if(nums.size() < 1) return ans;
// 首先排序
sort(nums.begin(), nums.end());
vector<int> tmp;
dfs(0, tmp, ans, nums);
return ans;
}
};


2. map + dfs, 本质上与第一种解法相同,因为map将所有的相同的元素都几种在一个对应关系上,这样就可以直接只遍历一个元素。该解法 8ms beats 75.43% of cpp submissions.

class Solution {
public:
void dfs(vector<int>& tmp, vector<vector<int>>& ans, map<int, int>& nmap, map<int, int>::iterator begin){
ans.push_back(tmp);

for(map<int, int>::iterator iter = begin; iter != nmap.end(); ++ iter) {
if(iter->second){
tmp.push_back(iter->first);
(iter->second) --;
dfs(tmp, ans, nmap, iter);
(iter->second) ++;
tmp.pop_back();
}

}

}

vector<vector<int>> subsetsWithDup(vector<int>& nums) {
vector<vector<int>> ans;
if(nums.size() < 1) return ans;
map<int, int> nmap;
for(int i = 0; i < nums.size(); ++ i) {
nmap[nums[i]] ++;
}
vector<int> tmp;
dfs(tmp, ans, nmap, nmap.begin());
return ans;
}
};


3. 利用之前已有的序列,不断的对已有序列进行填充。如 1, 1, 2, 3, 3, 5. ans中初始化的结果是一个空集[]

对于1,1 取出[], 将[1], [1, 1]分别和[]合并,压入结果序列,此时结果序列ans为[], [1], [1,1]

对于2, 取出[], [1], [1,1], 此时将[2]与前3者合并,结果为[2], [1, 2], [1, 1, 2],加入结果序列ans, 此时结果为[], [1], [1, 1], [2], [1, 2], [1, 1, 2]。

......以此类推。该解法:12ms, beats 22.32%
of cpp submissions

class Solution {
public:

vector<vector<int>> subsetsWithDup(vector<int>& nums) {
vector<vector<int>> ans;
if(nums.size() < 1) return ans;
map<int, int> nmap;
for(int i = 0; i < nums.size(); ++ i) {
nmap[nums[i]] ++;
}

ans.push_back(vector<int>());
map<int, int>::iterator iter = nmap.begin();

while(iter != nmap.end()) {
int cnt = iter->second;
int previousN = ans.size();
for(int j = 0; j < previousN; ++ j) {
vector<int> tmp = ans[j];
for(int k = 0; k < cnt; ++ k) {
tmp.push_back(iter->first);
ans.push_back(tmp);
}
}
++ iter;
}

return ans;
}
};


与此题类似的题目有
78.subsets 77.combinations
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: