- 深搜时候给足限制条件
- 博客来源:LawsonAbs@CSDN
这题不像简单的全排列,还是有那么一丢丢的思考在里面。主要考察的点有两个:
- 如何写递归完成搜索的过程?
- 如何控制不重复的采样?在不使用
set
的情况下。 - 如何获取各个长度的子集?
第一个问题很好解决,就类似于全排列,直接挨个遍历即可。
第二个问题是关键:如何保证挨个遍历的时候,不重复?如果完全按照全排列,肯定会重,如先获取了[1,2,3]
,接着又访问了[1,3,2]
,那么怎么解决呢?我们可以在深搜的时候给一个下标阈值,用于限定只能在这个范围内采样,这样当搜索到[1,3]
中的3时,因为2的下标小于3,不会再往前寻找了。这时候遍历就结束了。
第三个问题同样也比较好解决,一个集合的子集长度分别从0 到 n,所以每次遍历的时候,我们限制一下获取的集合的长度即可。
综上所述,可得如下代码:
代码from copy import copy
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
res = [[]]
if len(nums) == 0:
return res
# 子集的长度,从0 到 n
# 怎么避免重复?当前的这个数搞过了,就再也不会被遍历
for all_len in range(1,len(nums)):
vis = [0] * len(nums)
for i in range(len(nums)): # 每个数都有组成长度为 all_len 的资格
vis[i] = 1
cur = [] # 当前此次循环的
cur.append(nums[i])
self.dfs(nums,res,cur,all_len,vis,i+1)
res.append(copy(nums))
return res
# start 表示搜索的起始下标
def dfs(self,nums,res,cur,all_len,vis,start):
if len(cur) == all_len:
res.append(copy(cur))
return
for i in range(start,len(nums)):
if vis[i] == 0:
vis[i] = 1
cur.append(nums[i])
self.dfs(nums,res,cur,all_len,vis,i+1)
cur.pop()
vis[i] = 0