leetcode 78 子集 回溯演算法 詳解!

2021-10-10 18:57:13 字數 2026 閱讀 4623

本文 已經收錄,裡面還有leetcode刷題攻略、各個型別經典題目刷題順序、思維導圖,可以fork到自己倉庫,有空看一看一定會有所收穫,如果對你有幫助也給乙個star支援一下吧!

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

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

示例:輸入: nums = [1,2,3]

輸出:[

[3],

[1],

[2],

[1,2,3],

[1,3],

[2,3],

[1,2],

]求子集問題和回溯演算法:求組合問題!和回溯演算法:分割問題!又不一樣了。

如果把 子集問題、組合問題、分割問題都抽象為一棵樹的話,那麼組合問題和分割問題都是收集樹的葉子節點,而子集問題是找樹的所有節點!

其實子集也是一種組合問題,因為它的集合是無序的,子集 和 子集是一樣的。

那麼既然是無序,取過的元素不會重複取,寫回溯演算法的時候,for就要從startindex開始,而不是從0開始!

有同學問了,什麼時候for可以從0開始呢?

求排列問題的時候,就要從0開始,因為集合是有序的, 和是兩個集合,排列問題我們後續的文章就會講到的。

以示例中nums = [1,2,3]為例把求子集抽象為樹型結構,如下:

從圖中紅線部分,可以看出遍歷這個樹的時候,把所有節點都記錄下來,就是要求的子集集合

全域性變數陣列path為子集收集元素,二維陣列result存放子集組合。(也可以放到遞迴函式引數裡)

遞迴函式引數在上面講到了,需要startindex。

**如下:

vector> result;

vectorpath;

void backtracking(vector& nums, int startindex)

其實可以不需要加終止條件,因為startindex >= nums.size(),本層for迴圈本來也結束了

求取子集問題,不需要任何剪枝!因為子集就是要遍歷整棵樹

那麼單層遞迴邏輯**如下:

for (int i = startindex; i < nums.size(); i++)
根據關於回溯演算法,你該了解這些!給出的回溯演算法模板:

void backtracking(引數) 

for (選擇:本層集合中元素(樹中節點孩子的數量就是集合的大小))

}

可以寫出如下回溯演算法c++**:

class solution 

for (int i = startindex; i < nums.size(); i++)

}public:

vector> subsets(vector& nums)

};

在注釋中,可以發現可以不寫終止條件,因為本來我們就要遍歷整顆樹。

有的同學可能擔心不寫終止條件會不會無限遞迴?

並不會,因為每次遞迴的下一層就是從i+1開始的。

相信大家經過了

分割問題:

洗禮之後,發現子集問題還真的有點簡單了,其實這就是一道標準的模板題。

但是要清楚子集問題和組合問題、分割問題的的區別,子集是收集樹形結構中樹的所有節點的結果

而組合問題、分割問題是收集樹形結構中葉子節點的結果

就醬,如果感覺收穫滿滿,就幫carl宣傳一波「**隨想錄」吧!

如果感覺對你有幫助,不要吝嗇給乙個?吧!

leetcode 78 子集 回溯法

給定一組不含重複元素的整數陣列 nums,返回該陣列所有可能的子集 冪集 說明 解集不能包含重複的子集。示例 輸入 nums 1,2,3 輸出 3 1 2 1,2,3 1,3 2,3 1,2 class solution return res void recruise vector int num...

LeetCode 78 子集 位運算 回溯演算法

給定一組不含重複元素的整數陣列 nums,返回該陣列所有可能的子集 冪集 說明 解集不能包含重複的子集。示例 輸入 nums 1,2,3 輸出 3 1 2 1,2,3 1,3 2,3 1,2 可以使用0 1序列來表示每個子集,0表示不包含此元素,1表示包含此元素。例如 1 100 1,2 110 1...

leetcode78子集 中等

給定一組不含重複元素的整數陣列 nums,返回該陣列所有可能的子集 冪集 說明 解集不能包含重複的子集。示例 輸入 nums 1,2,3 輸出 3 1 2 1,2,3 1,3 2,3 1,2 要列出陣列的所有子集,因為陣列是不含重複元素的,所以對於每乙個位置的數字,有兩個選擇,選或者不選。可以畫出以...