您的位置:首页 > 其它

Leetcode: Subsets II

2014-01-01 22:52 316 查看
Given a collection of integers that might contain duplicates, S, 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 S = 
[1,2,2]
, a solution
is:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]

跟I相比,输入可能包含重复元素,最懒的方法是在I的基础上去重。权当练习STL了吧。

class Solution {
public:
vector<vector<int> > subsetsWithDup(vector<int> &S) {
vector<vector<int> > result;
if (S.empty()) return result;

sort(S.begin(), S.end(), greater<int>());
int size = S.size();
int max_sets = pow(2, size);
for (int i = 0; i < max_sets; ++i) {
result.push_back(getElement(S, size, i));
}

sort(result.begin(), result.end(), myless);
vector<vector<int> >::iterator it = unique(result.begin(), result.end(), myequal);
result.resize(distance(result.begin(), it));

return result;
}

vector<int> getElement(vector<int> &S, int size, int index) {
vector<int> elem;
for (int i = 1; index > 0; ++i) {
if (index & 1) {
elem.push_back(S[size-i]);
}
index >>= 1;
}

return elem;
}

struct vector_less {
bool operator()(vector<int> v1, vector<int> v2) {
int size1 = v1.size();
int size2 = v2.size();
if (size1 != size2) {
return (size1 < size2);
}

for (int i = 0; i < size1; ++i) {
if (v1[i] != v2[i]) {
return (v1[i] < v2[i]);
}
}

return false;
}
} myless;

struct vector_equal {
bool operator()(vector<int> &v1, vector<int> &v2) {
int size1 = v1.size();
int size2 = v2.size();
if (size1 != size2) {
return false;
}

for (int i = 0; i < size1; ++i) {
if (v1[i] != v2[i]) {
return false;
}
}

return true;
}
} myequal;
};
网上搜了一下,另一种思想。如果是重复元素,则只加入到之前包含该元素的集合中,因为加入到不包含该元素的集合会产生重复。

class Solution {
public:
vector<vector<int> > subsetsWithDup(vector<int> &S) {
sort(S.begin(), S.end());
vector<vector<int> > result(1); // Add an empty vector
int prestart = 0;
int start = 0;
for (int i = 0; i < S.size(); ++i) {
int j = result.size();
if (i != 0 && S[i] == S[i-1]) {
start = prestart;
}
else{
start = 0;
}
prestart = j;
while (j-- > start) {
result.push_back(result[j]);
result.back().push_back(S[i]);
}
}

return result;
}
};
还有一种DFS的方法,暂时没弄清楚。啥时候能整明白呢?:(

=================第二次==============
DFS来了,思路简单,就是大杀器啊。同样需要注意去重,多个相等元素只有前面加入了后面的才能加入。
class Solution {
public:
vector<vector<int> > subsetsWithDup(vector<int> &S) {
vector<vector<int>> result;
vector<int> subset;
vector<bool> used(S.size(), false);

sort(S.begin(), S.end());
subsets_util(result, subset, S, used, 0);

return result;
}

void subsets_util(vector<vector<int>> &result, vector<int> &subset,
const vector<int> &S, vector<bool> &used, int step) {
if (step == S.size()) {
result.push_back(subset);
return;
}

subsets_util(result, subset, S, used, step+1);

if (step == 0 || S[step] != S[step-1] || used[step-1]) {
subset.push_back(S[step]);
used[step] = true;
subsets_util(result, subset, S, used, step+1);
subset.pop_back();
used[step] = false;
}
}
};


还有一种去重的方法,就是把vector的结果暂存到集合里面,利用集合的性质来自然去重,最后再遍历放到结果vector里面去。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode dfs