c_cpp [子集I]给定一组不同的整数S,返回所有可能的子集。注意:子集中的元素必须按非降序排列。 Ť

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp [子集I]给定一组不同的整数S,返回所有可能的子集。注意:子集中的元素必须按非降序排列。 Ť相关的知识,希望对你有一定的参考价值。

// there are two solutions. One is the normal DFS using the ordinary logic. The other is different. 
// Its advantage is that, its logic can be extented to the "Subsets II" problem with only little updates.

// Solution 1: normal dfs, easy to think, but cannot handle duplications.
// idea: contain or not contain a certain item in the set
void DFS(vector<vector<int>> &res, vector<int> one_subset, vector<int> &S, int i, int N) {
	if(i == N) {
		res.push_back(one_subset);
		return;
	}
	DFS(res, one_subset, S, i+1, N); // do not contain S[i]
	one_subset.push_back(S[i]);
	DFS(res, one_subset, S, i+1, N); // contain S[i]
	one_subset.pop_back();
} 

vector<vector<int>> subsets(vector<int> &S) {
	vector<vector<int>> res;
	if(S.empty()) return res;
	sort(S.begin(), S.end()); // gist
	vector<int> one_subset;
	DFS(res, one_subset, S, 0, S.size());
	return res;
}

// ---------------------------------------------------------------------------------------
// Solution 2: best version.
// sort, then consider one by one. The idea is quite different from the above one.
void DFS2(vector<vector<int>> &res, vector<int> onesubset, vector<int> &S, int pos) {
    for(int i=pos; i<S.size(); i++) {
    	if(i > pos && S[i] == S[i-1]) continue; // gist5, handle duplicate elements in set!
        onesubset.push_back(S[i]);
        res.push_back(onesubset);   // gist3, everytime we update onesubset, we add it to final res
        DFS2(res, onesubset, S, i+1);
        onesubset.pop_back();
    }
}

vector<vector<int>> subsets(vector<int> &S) {
    vector<vector<int>> res;
	if(S.empty()) return res;
	sort(S.begin(), S.end());   // gist1, sort
	vector<int> one_subset;
	res.push_back(one_subset);  // gist2, push an empty item beforehand. 
	DFS2(res, one_subset, S, 0);
	return res;
}

// ---------------------------------------------------------------------------------------
// solution 3, push to res outside of loop. little hard to think.
void DFS3(vector<vector<int>>& res, vector<int> onesubset, vector<int>& S, int pos) {
    res.push_back(onesubset); // push before loop
    for(int i=pos; i<S.size(); i++) {
        if(i > pos && S[i] == S[i-1]) continue; // handle duplications
        onesubset.push_back(S[i]);
        DFS3(res, onesubset, S, i+1);
        onesubset.pop_back();
    }
}
vector<vector<int>> subsets(vector<int>& S) {
    vector<vector<int>> res;
    if(S.empty()) return res;
    sort(S.begin(), S.end());
    vector<int> one_subset;
    DFS3(res, one_subset, S, 0);
    return res;
}



// Example: expand the recursive function DFS2 on set S = [1,2,3].
/*
S = [1,2,3]
dfs2(res, [], S, 0) {
    i=0
    onesubset = [1]             <------
    res = [[1]]
    dfs2(res, [1], S, 1) {
        i=1
        onesubset=[1,2]         <------
        dfs2(res, [1,2], S, 2) {
            i=2
            onesubset=[1,2,3]   <------
            dfs2(res, [1,2,3], S, 3)
            onesubset=[1,2]
        }
        onesubset=[1]
        
        i=2
        onesubset=[1,3]         <------
        dfs2(res, [1,3], S, 3)
        onesubset=[1]
        
    }
    onesubset = []
    
    i=1
    onesubset = [2]             <------
    res = [[...], [...], [2]]
    dfs2(res, [2], S, 2) {
        i=2
        onesubset=[2,3]         <------
        dfs2(res, [2,3], S, 3)
    }
    onesubset = []
    
    i=2
    onesubset=[3]               <------
    res = [[...], [...], ..., [3]]
    dfs2(res, [3], S, 3)
    onesubset=[]
}
*/



以上是关于c_cpp [子集I]给定一组不同的整数S,返回所有可能的子集。注意:子集中的元素必须按非降序排列。 Ť的主要内容,如果未能解决你的问题,请参考以下文章

给定一组 ID,返回仅具有这些 ID 的订单子集

c_cpp 给定一组单词,返回给定集合中的anagrams集合

LeetCode子集问题

078 Subsets 子集

DFS_78. 子集

c_cpp 给定一组数字,返回所有可能的排列。例如,[1,2,3]具有以下排列:[1,2,3],[1,3,2],[2