探索 中級演算法 子集

2021-09-01 02:37:49 字數 2260 閱讀 1733

這裡題目沒有要求子集內的元素必須公升序,也沒有要求所有子集的排列順序,且沒有重複的元素。

參考自:

解法一 迭代

對於題目中給的例子[1,2,3]來說,最開始是空集,那麼我們現在要處理1,就在空集上加1,為[1],現在

有兩個自己和[1],下面來處理2,我們在之前的子集基礎上,每個都加個2,可以分別得到[2],[1, 2],

那麼現在所有的子集合為, [1], [2], [1, 2],同理處理3的情況可得[3], [1, 3], [2, 3],

[1, 2, 3], 再加上之前的子集就是所有的子集合了

public list

>

subsets

(int

nums)

result.

addall

(tmpresult);}

}return result;

}

解法二 遞迴
由於原集合每乙個數字只有兩種狀態,要麼存在,要麼不存在,那麼在構造子集時就有選擇和不選擇兩種情況,

所以可以構造一棵二叉樹,左子樹表示選擇該層處理的節點,右子樹表示不選擇,最終的葉節點就是所有子集合,

樹的結構如下:

/ \

/ \

/ \

[1]

/ \ / \

/ \ / \

[1 2] [1] [2]

/ \ / \ / \ / \

[1 2 3] [1 2] [1 3] [1] [2 3] [2] [3]

list

> result =

newlinkedlist

<

>()

;public list

>

subsets

(int

nums)

return result;

}public

void

dfs(

int[

] nums,

int i,list

tmp)

list

another =

newarraylist

<

>

(tmp)

; another.

add(nums[i]);

dfs(nums, i +

1, tmp)

;dfs

(nums, i +

1, another)

;}

解法三
把陣列中所有的數分配乙個狀態,true表示這個數在子集中出現,false表示在子集中不出現,那麼對於乙個

長度為n的陣列,每個數字都有出現與不出現兩種情況,所以共有2n中情況,那麼我們把每種情況都轉換出來

就是子集了

為了更加直觀的講解,對於 true 用 1 代替,false 則用 0 代替。

則對於[1, 2, 3],總共有 8 個子集,對於每乙個子集,都由子集序數的二進位制進一步對映得到,比如第 0 個子集,此時子集序數為 0,其二進位制為000,而每一位0則代表對應位置上的nums[idnex]不在第 0 個子集中,因此就有:

}解法利用了組合的規律,很巧妙,且因為沒有重複元素,所以在處理上比較簡單直接。

swift演算法 子集

1 描述 給定一組不含重複元素的整數陣列 nums,返回該陣列所有可能的子集 冪集 說明 解集不能包含重複的子集 例 輸入 nums 1,2,3 輸出 3 1 2 1,2,3 1,3 2,3 1,2 2 演算法 1 二進位制位 思想 集合的每個元素,都有可以選或不選,用二進位制和位運算,可以很好的表...

演算法 子集和問題

子集和問題就是 給出乙個陣列arr和乙個值sum 輸出滿足和為sum的arr的子集 子集和問題 從某種程度上來說 其實就是 01揹包問題的 子問題 還是取一種情況 不取是另外一種情況 然後 用回溯法 構建出一棵樹來遍歷一下 include include using namespace std co...

回溯演算法 子集II

思路 該題為子集問題,與之前 組合總和問題ii 的去重思想一致,即相同一層不能有相同的元素,因此去重邏輯 if i startidex nums i nums i 1 不變,注意要先排序,將相同元素放在一起 class solution void backtrack vector int nums,...