1. 程式人生 > >leetcode-78-子集(用bfs解決)

leetcode-78-子集(用bfs解決)

們的 過程 bsp 二維 eight beat front pan 圖片

題目描述:

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

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

示例:

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

要完成的函數:

vector<vector<int>> subsets(vector<int>& nums)

說明:

1、這道題給定一組不重復的元素,要求返回這組元素所有可能的子集,也就是返回冪集。

每個可能的子集存儲在一維vector中,所有的子集合起來存儲在二維的vector中。

2、舉個例子,給定的vector是[1,2,3,4]。

那我們人類在做這道題的時候,都是想:

0個元素的:[]

1個元素的:1 2 3 4

2個元素的:12 13 14 23 24 34

3個元素的:123 124 234

4個元素的:1234

2個元素的子集,是在1個元素的子集的基礎上形成的。

比如1可以擴散出12 13 14,2可以擴散出23 24……

這像是樹開枝散葉,往外擴散的樣子?

我們這樣子看:

技術分享圖片

我們其實最後要的是寬度優先搜索這棵樹的結果。

所以這道題其實是一道BFS(寬度優先搜索)的題目,用熟悉的隊列就可以解決。

代碼如下:(附詳解)

    void bfs(vector<vector<int>>& res,queue<vector<int>>& q,int s1,vector<int>& nums)
    {//這裏要帶上&,指針,傳參數快,而且在存儲空間中修改了res的值,最後也能在subsets函數中得到
        int i,count=1;
        while(!q.empty())//當存儲中間過程的數據不空
        {
            for(int j:q.front())//把第一個vector中的坐標數據讀出來,插入到res[count]中,最開始是[0]
                res[count].push_back(nums[j]);
            count++;
            i=q.front().back();//得到最後一個坐標,i=0
            while(i+1<s1)
            {
                q.push(q.front());在q的末尾插入[0]
                q.back().push_back(i+1);//在q的最後一個vector,也就是剛剛插入的[0],再插入1,形成[0,1]
                i++;//i++,不斷循環
            }
            q.pop();//去掉第一個vector,最開始時是[0]
        }
    }
    vector<vector<int>> subsets(vector<int>& nums) 
    {
        int s1=nums.size();
        vector<vector<int>>res(pow(2,s1),vector<int>{});//提前申請好2^s1個vector<int>空間
        queue<vector<int>>q;//我們用隊列來存儲中間過程的數據
        for(int i=0;i<s1;i++)//如果給定nums是[1,2,3],那麽這裏存儲它們的坐標[0],[1],[2]
            q.push({i});
        bfs(res,q,s1,nums);//帶著res的指針和q的指針以及nums這些數據,進入bfs函數
        return res;//返回最終的res
    }

上述代碼其實就是bfs的實現過程,只不過我們沒有真的去建樹,直接把數據插入到隊列中。

上述代碼實測4ms,beats 100.00% of cpp submissions。

leetcode-78-子集(用bfs解決)