給定一組不含重複元素的整數數組 nums,返回該數組所有可能的子集(冪集)。
說明:解集不能包含重複的子集。
示例:
輸入: nums = [1,2,3]
輸出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
解法一:位運算
這個方法最核心的思想是第i個子集的二進制正好對應着其子集。對應關係如下:
如輸入 [1,2,3],輸出排列方式有8種,依次將1往左移位和原數進行與運算 1<<j&i 1<<j \quad \&\quad i1<<j&i
[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
可以對應到如下的8中標記
0 0 0 , 0 0 1 , 0 1 0 , 0 1 1,1 0 0 , 1 0 1 , 1 1 0 , 1 1 1
其中很明顯可以看出一個子集中存在的元素正好對應着位爲1。
第一步:我們計算有2**len(nums)個子集。
第二步:第i個子集對應着數i。利用位運算,如果1 << j & i 得到的結果不爲0,則說明本子集第j個元素存在。
簡化版代碼:運行時間相比於下面那個代碼更長
class Solution(object):
def subsets(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
ans = []
for i in range(2**len(nums)):
ans.append([nums[j] for j in range(len(nums)) if 1 << j & i])
return ans
下面這個代碼更容易理解一些:
class Solution(object):
def subsets(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
len_nums = len(nums)
total = 2**len_nums
res =[]
for i in range(total):
flag_list = [0 for k in range(len_nums)] # 用flag_list標記對應的每個是否存在
for j in range(len_nums):
bit = 1<<j
if bit & i:
flag_list[j] = 1
lists = [nums[j] for j in range(len_nums) if flag_list[j] == 1]
res.append(lists)
return res