LeetCode全排列 回溯与递归
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例 1:
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
示例 2:
输入:nums = [0,1]
输出:[[0,1],[1,0]]
示例 3:
输入:nums = [1]
输出:[[1]]
思路:
直接说方法,就是回溯+递归!可以参考39. 组合总和
我们同样想象一棵选择树,对于数组[1,2,3],一开始抓取,可以抓1或2或3——说明我们依然要通过回溯的方式来尝试所有的选择。
我们定义递归函数,同样是有两个参数(has, choose),但因为这一题是不放回的抓取,所以我们每次递归时,需要判断当前选择是否已经选了,已经有了则跳过。当现有has长度等于给定选择列表时,我们就存入结果。
最后老生常谈的是:每次送入递归之后要马上退回当前状态,这就是经典回溯了。
代码:
class Solution(object):
def permute(self, nums):
res=[] #存储结果的列表
lenth = len(nums)
def di(has,choose):
if len(has)==lenth:#base case上来写
res.append(has[:])#重点1 放的是个copy切片
for cho in choose:
if cho not in has:#重点2判断has是否已有这个选择
has.append(cho)#若没有 加入这个选择
di(has,choose)#送入递归
has.pop()#恢复状态
di([],nums)#开始has为空,选择列表为nums
return res
小结:
总之这个题是很基础的了,基本上回溯相关的问题我都是采用类似的像模板一样去做的。
这里有个小坑,我们存入res结果的列表,要是切片,因为切片是额外复制出的一份,假如不是切片,则后面会被莫名其妙地修改!你自己都找不到原因。所以这里要特别注意!
原本对于“不放回”的回溯,我们是要每次更新选择列表的,但那样操作起来麻烦很大。因此直接每次选择时来判断是否已经选了,通过这种方式来避免重复选择,就容易实现多了。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 我与微信审核的“相爱相杀”看个人小程序副业
· DeepSeek “源神”启动!「GitHub 热点速览」
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库