1. 程式人生 > 實用技巧 >78:子集(C++)

78:子集(C++)

題目地址:https://leetcode-cn.com/problems/subsets/

題目描述

給定一組不含重複元素的整數陣列nums,返回該陣列所有可能的子集(冪集)。

說明:解集不能包含重複的子集。

題目示例

示例:

輸入: nums = [1,2,3]
輸出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]

解題思路

思路1:動態規劃。我們使用二維陣列進行儲存,首先儲存陣列nums中的每個元素自身,然後以該元素為起點,分別遍歷查詢nums陣列其它元素,最後將其加入到結果集中。

思路2:遞迴求解。我們可以發現,當陣列nums的元素為n時,其子集的數目為2^n個,而每個子集可以看作是對陣列nums中的每個元素是否新增的過程,即選不選的問題,如果選,則把它加入進來,然後將所維護的陣列元素減少一個;如果不選,則維護的陣列不變。

程式原始碼

思路1

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> res;
        if(nums.empty()) return res;
        res.push_back({});
        // 當前加入的元素值為nums[i]
        for(int i= 0; i < nums.size(); i++)
        {
            
int len = res.size(); // 前面i-1個子集中的元素個數 // 將nums[i]分別放入res[j]的各個vect中,再放進res中 for(int j = 0; j < len; ++j) { // 將nums[i]放入空集中 if(res[j].size() == 1) res.push_back({nums[i]}); else{ vector<int> temp; temp
= res[j]; temp.push_back(nums[i]); res.push_back(temp); } } } return res; } };

思路2

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> res; //結果集
        vector<int> list; //維護nums陣列元素
        if(nums.empty()) return res;
        dfs(res, nums, list, 0);
        return res;
    }
    void dfs(vector<vector<int>>& res, vector<int>& nums, vector<int>& list, int index)
    {
        //遞迴終止條件
        if(index == nums.size())
        {
            res.push_back(list);
            return;
        }
        //遞迴求解,即處理當前層
        dfs(res, nums, list, index + 1); //不選該數,使得list不變

        list.push_back(nums[index]);
        dfs(res, nums, list, index + 1); //選擇該數
        //清掃當前層的狀態
        list.pop_back();
    }
};