1、描述
給定一組不含重複元素的整數陣列 nums,返回該陣列所有可能的子集(冪集)。
說明:解集不能包含重複的子集
例:輸入:nums = [1, 2, 3]
輸出:[ [3], [1], [2], [1, 2, 3], [1, 3], [2, 3], [1, 2], ]
2、演算法
1)二進位制位
思想:集合的每個元素,都有可以選或不選,用二進位制和位運算,可以很好的表示
func subsets(_ nums: [int]) -> [[int]] }}
return res
}
2)列舉
解法一:逐個列舉
思想:逐個列舉,空集的冪集只有空集,每增加乙個元素,讓之前冪集中的每個集合,追加這個元素,就是新增的子集
func subsets(_ nums: [int]) -> [[int]]
private func recursion(_ nums : [int], _ i : int, _ res : inout [[int]])
let size = res.count
var j = 0
while j < size
recursion(nums, i+1, &res)
}
3)迭代
解法一思想:解法一的迭代法,是直接從結果上進行分類,將子陣列的長度分為長度是 1 的,2 的 .... n 的。
想找出陣列長度 1 的所有解,然後再在長度為 1 的所有解上加 1 個數字變成長度為 2 的所有解,同樣的直到 n。
示意圖:
第一次迴圈: [1] [2] [3]
第二次迴圈:[1, 2] [1, 3] [2, 3]
第三次迴圈:[1, 2, 3]
func subsets(_ nums: [int]) -> [[int]]
var newlist = [int](list)}}
ans=tmp
}return res
}
解法二
思想:我們還可以從條件上入手,先只考慮給定陣列的 1 個元素的所有子陣列,然後再考慮陣列的 2 個元素的所有子陣列 ... 最後再考慮陣列的 n 個元素的所有子陣列。求 k 個元素的所有子陣列,只需要在 k - 1 個元素的所有子陣列裡邊加上 nums [ k ] 即可。
圖示: --> 初始化空
[1] --> [1]
[1] [2] [1,2] --> [1,2]
[1] [2] [1, 2] [3] [1,3] [2,3] [1,2,3] --> [1,2,3]
func subsets(_ nums: [int]) -> [[int]]
private func backtrace(_ nums : [int], _ i : int, _ sub : inout [int], _ res : inout [[int]])
}
探索 中級演算法 子集
這裡題目沒有要求子集內的元素必須公升序,也沒有要求所有子集的排列順序,且沒有重複的元素。參考自 解法一 迭代 對於題目中給的例子 1,2,3 來說,最開始是空集,那麼我們現在要處理1,就在空集上加1,為 1 現在 有兩個自己和 1 下面來處理2,我們在之前的子集基礎上,每個都加個2,可以分別得到 2...
演算法 子集和問題
子集和問題就是 給出乙個陣列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,...