python
class Solution:
def permute(self, nums: list[int]) -> list[list[int]]:
ans=[]
path=[]
used=[False]*len(nums)
def back():
if len(path)==len(nums):
ans.append(path[:])
return
for i in range(len(nums)):
if used[i]:
continue
used[i]=True
path.append(nums[i])
back()
path.pop()
used[i]=False
back()
return ans
python
class Solution:
def subsets(self, nums: list[int]) -> list[list[int]]:
q=[[]]
n=len(nums)
for i in range(0,len(nums)):
for j in range(0, len(q)):
q.append(q[j]+[nums[i]])
return q
注意:① 双层循环;② nums\[i],注意切勿漏掉外层括号;③ 该题解法为 "迭代" 思路
python
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
res = []
path = []
def backtrack(left, right): # left/right:已放的左/右括号数
if len(path) == 2 * n: # 放满 2n 个,按规则走来必然合法
res.append(''.join(path))
return
if left < n: # 分支一:左括号还有余量
path.append('(')
backtrack(left + 1, right)
path.pop() # 撤销,好让下面的 if 从同一状态出发
if right < left: # 分支二:有未配对的左括号才能放右
path.append(')')
backtrack(left, right + 1)
path.pop()
# 此处两个 0 指的是使用左右括号的数量
backtrack(0, 0)
return res
39. 组合总和 - 力扣(LeetCode)(核心思想:回溯+剪枝)
python
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
res = []
path = []
candidates.sort() # 排序是为了下面能 break 剪枝
def backtrack(start, remain): # remain:还差多少凑够 target
if remain == 0: # 恰好凑够,收集
res.append(path[:])
return
for i in range(start, len(candidates)):
if candidates[i] > remain: # 已排序,当前超额则后面都超额
break # break 不是 continue:整层剩下全砍
path.append(candidates[i]) # 做选择
backtrack(i, remain - candidates[i]) # 传 i:自己还能再选一次
path.pop() # 撤销
backtrack(0, target)
return res
注意易错点:Python 列表的 .pop() 方法 默认只弹出并移除列表的最后一个元素,不会清空整个列表,它是「逐个弹出」的操作。