标签:
跟Subsets(参见这篇文章)类似。
但因为有重复元素,所以要考虑去重问题。
什么情况下会出现重复呢?比如S = {5, 5, 5},如果要选1个5,一共有C(3,1)=3种选法,即100, 010, 001,这三种情况在集合的角度看是重复的情况。如果要选2个5,共有C(3,2)=3种选法,即011, 101, 110,这三种情况在集合的角度上看也是重复的。
本质在于,如果要在重复出现的数字当中选择若干个,则只能保留一种取法,其他的都是重复。即,这些重复数字对应的二进制位当中,只能保留一个指定若干位为1的数字。前面的例子中,如果要在S种取2个5,则011, 101, 110这三个数字(二进制为都有2个位为1)只能保留一个。保留哪个呢?随便,不过为了方便编码实现,可以保留1都在左边的数字。上面的例子中,保留110。
如果用DFS实现,也是类似的思想,当搜索到某个数字时,如果决定不选了,那么之后同样的数字也都不再选了。(相当于保证1都出现在二进制数字的左边)。
代码(DFS版):
1 vector<vector<int> > res; 2 3 void dfs(vector<int> &S, vector<int> ans, int pos) { 4 if (pos == S.size()) { 5 res.push_back(ans); 6 return; 7 } 8 ans.push_back(S[pos]); 9 dfs(S, ans, ++pos); 10 ans.pop_back(); 11 while (pos < S.size() && S[pos] == S[pos - 1]) 12 pos++; 13 dfs(S, ans, pos); 14 } 15 16 vector<vector<int> > subsetsWithDup(vector<int> &S) { 17 sort(S.begin(), S.end()); 18 dfs(S, vector<int>(), 0); 19 return res; 20 }
标签:
原文地址:http://www.cnblogs.com/boring09/p/4259454.html