对于回溯算法的入门理解,weiwei大佬这个讲解思路还挺友好的,还有labuladong
刚接触会懵就对了(此刻的我),多测试debug看数据是如何运行的,应该慢慢就能领悟了…
我也不知道为什么一开始就是中等题♂️,因为刚好力扣每日打卡今天是这题,打开题解都是以这道题为例子,可能是以前学过全排列所以比较好理解,那就撸起袖子加油干把
题目:给定一个 没有重复 数字的序列,返回其所有可能的全排列。
思路:采用深度优先搜索+ 状态重置
1.设置depth来表示递归到树的第几层;因为节点要不重复,初始化used=[False for _ in range(len(nums)],当对应位置为True表示此结点已被选择的;path记录选择结果,表示包含至当前已选择的节点,res存贮最后的结果
2.采用深度优先搜索,从根结点到遍历到最深层结点,从nums中依次存入path中【不重复】,因此用used要判断。当从最深层结点返回到较浅层结点时,需要做状态重置,[1, 2, 3] 回到 [1, 2] 的时候,需要撤销刚刚已经选择的数 3。从深层结点回到浅层结点的过程中所做的操作就叫“回溯”。
def permute(self, nums: List[int]) -> List[List[int]]:
def dfs(nums,size,depth,path,used,res):
if depth==size: # 结束条件是寻找深度达到目标深度
res.append(path[:]) #注意path[:]
return #结束该层递归
for i in range(size):
if used[i]==False: #记录是否已选择
used[i]=True # 将访问过的元素标记
path.append(nums[i]) #记录选择的结果
dfs(nums,size,depth+1,path,used,res)
used[i]=False # 恢复到之前状态
path.pop() # 恢复到之前状态
used=[False for _ in range(len(nums))]
size = len(nums)
if size==0:
return []
res=[]
dfs(nums,size,0,[],used,res)
return res
题目:给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
有效的 IP 地址正好由四个整数(每个整数位于 0 到 255 之间组成),整数之间用 ‘.’ 分隔。
示例:
输入: “25525511135”
输出: [“255.255.11.135”, “255.255.111.35”]
思路:采用回溯算法:选择+搜索+状态重置
选择:切出三种长度
搜索:满足题目条件约束(剪枝),一个片段的长度在1-3,片段有效值为0-255,没有“0x”等开头
状态重置:生成4个有效长度片段,并且字符串中所有字符都要用完。
class Solution:
def restoreIpAddresses(self, s: str) -> List[str]:
def traceback(num, temp, s):
if num==4 and not s:
res.append(temp[:-1])
return
for i in range(1,4):
if i<=len(s) and int(s[:i])<=255 and (s[0]>'0' or s[:i]=='0'):
traceback(num+1,temp+s[:i]+'.', s[i:] if i<len(s) else "")
res = []
if len(s)<=12:
traceback(0, "", s)
else:
return []
return res