全子集問題(subset)

全子集問題的三種解法:

1.回溯法
回溯是經典的解法,有固定的模板,用遞歸實現。

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        vector<vector<int>> subs;
        vector<int> sub;  
        genSubsets(nums, 0, sub, subs);
        return subs; 
    }
    void genSubsets(vector<int>& nums, int start, vector<int>& sub, vector<vector<int>>& subs) {
        subs.push_back(sub);
        for (int i = start; i < nums.size(); i++) {
            sub.push_back(nums[i]);
            genSubsets(nums, i + 1, sub, subs);
            sub.pop_back();
        }
    }
};

2.迭代法
初始爲空集[ ]
將上一次的解複製一遍,並往里加元素[ ][ ]→[][1]
將上一次的解複製一遍,並往里加元素[ ][1][ ][1]→[ ][1][2][1,2]
重複複製步驟[ ][1][2][1,2][ ][1][2][1,2]→[ ][1][2][1,2][3][1,3][2,3][1,2,3]

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

3.bit映射法
000~111共8種排列,對應着8種子集,每一bit對應着一個元素

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        int num_subset = pow(2, nums.size()); 
        vector<vector<int> > res(num_subset, vector<int>());
        for (int i = 0; i < nums.size(); i++)
            for (int j = 0; j < num_subset; j++)
                if ((j >> i) & 1)
                    res[j].push_back(nums[i]);
        return res;  
    }
};

【Reference】
https://leetcode.com/discuss/46668/recursive-iterative-manipulation-solutions-explanations

發佈了98 篇原創文章 · 獲贊 41 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章