标签:
Given a collection of integers that might contain duplicates, S, return all possible subsets.
Note:
For example,
If S = [1,2,2]
, a solution is:
[ [2], [1], [1,2,2], [2,2], [1,2], [] ]
Array Backtracking
思路:在subsets 思路四的基础上去重,如有3个2,标记为2a, 2b, 2c, 则加入2a,到2b是判读发现和前面的一样,那么只有当2b作为开头是可以加入,否则就不能加入。
也就是,idx==dep时,可以加入。
为什么呢? 从dfs(0)考虑,以2a开头和以2b开头是一样的,所以如果2a开头了,2b就不用开头了,那为什么idx==dep时2b可以加入呢?
因为2a开头是会调用下一层,到了2b,这时是可以加入的,构成2a,2b,也就是两个2的情况;同理既然2b加入了,2c就不用加入了,因为{2a,2b}和{2a,2c}是一样的。
class Solution { vector<vector<int> > m_res; vector<int> m_array; public: void dfs(int dep, vector<int> &S) { m_res.push_back(m_array); for(int idx = dep; idx < S.size(); idx ++) { // just add the first elements if there are some duplicates // if idx == dep, it should be added if(idx != dep && S[idx] == S[idx-1]) continue; m_array.push_back(S[idx]); dfs(idx + 1, S); m_array.pop_back(); } } vector<vector<int> > subsetsWithDup(vector<int> &S) { sort(S.begin(), S.end()); dfs(0, S); return m_res; } };
class Solution { vector<vector<int> > m_res; vector<int> m_array; vector<bool> m_canUse; public: void dfs(int dep, vector<int> &S) { m_res.push_back(m_array); for(int idx = dep; idx < S.size(); idx ++) { if(idx > 0 && m_canUse[idx-1] == true && S[idx] == S[idx-1]) continue; m_array.push_back(S[idx]); m_canUse[idx] = false; dfs(idx + 1, S); m_array.pop_back(); m_canUse[idx] = true; } } vector<vector<int> > subsetsWithDup(vector<int> &S) { sort(S.begin(), S.end()); m_canUse.clear(); m_canUse.resize(S.size(), true); dfs(0, S); return m_res; } };
思路二 :用一个数组来记录某个数字是否被使用过,如果前面的数字和本数相同,则前面的数必须被使用过本数才能被使用。
标签:
原文地址:http://www.cnblogs.com/diegodu/p/4378556.html