Subsets

Given a set of distinct integers, 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,3], a solution is:

[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]
分析:这道题是暴力枚举法很好的例子,代码可以作为以后其他变形题的模板。这里介绍递归和迭代两种方法,递归方法比较常见,迭代方法则巧妙些。
递归代码如下:
class Solution {
public:
    vector<vector<int> > subsets(vector<int> &S) {
        vector<vector<int> > result;
        vector<int> path;
        
        sort(S.begin(), S.end());
        get_subsets(result, path, S, 0);
        
        return result;
    }
    
    void get_subsets(vector<vector<int> > &result, vector<int> &path, vector<int> &S, int start){
        if(start == S.size()){
            result.push_back(path);
            return;
        }
        get_subsets(result, path, S, start+1);
        path.push_back(S[start]);
        get_subsets(result, path, S, start+1);
        path.pop_back();
    }
};

迭代法利用了数的二进制表示的特点,对于一个大小为n的set,其subset的个数是2^n,其生成过程可以抽象为一个长度为n的bit集合,如果ith bit位为1则选择set中的第i个元素,如果ith bit位为0则不选择set中的第i个元素。而上面所述的二进制数又对应于0到2^n - 1间的每一个整数。但这种方法的限制是n要小于等于32,否则subset的个数超过int的范围。

 1 class Solution {
 2 public:
 3     vector<vector<int> > subsets(vector<int> &S) {
 4         vector<vector<int> > result;
 5         
 6         sort(S.begin(), S.end());
 7         
 8         for(int i = 0; i < 1<<S.size(); i++){
 9             vector<int> path;
10             for(int j = 0; j < S.size(); j++){
11                 if(i & 1<<j) path.push_back(S[j]);
12             }
13             result.push_back(path);
14         }
15         
16         return result;
17     }
18 };

 再加一种迭代方法,当增加一个元素时,当前的subsets可以用由上一轮生成的subsets增量产生,具体方法是在保存上一轮原有subsets的同时,对于每一个subsets将当前元素添加在每个subsets的末尾。代码如下:

class Solution {
public:
    vector<vector<int> > subsets(vector<int> &S) {
        vector<vector<int> > result(1, vector<int>());
        
        sort(S.begin(), S.end());
        
        for(int i = 0; i < S.size(); i++){
            int result_size = result.size();
            for(int j = 0; j < result_size; j++){
                result.push_back(result[j]);
                result.back().push_back(S[i]);
            }
        }
        
        return result;
    }
};

 

posted on 2014-08-12 00:44  Ryan-Xing  阅读(190)  评论(0编辑  收藏  举报