前言:复习回溯算法
回溯算法的主要结构:
递归函数
if(终止条件)
for(遍历各个子节点){
处理结点
递归函数
撤销结点
}
93.复原IP地址
- 如何描述切割垫
- 怎样对子串的合法性进行判断
- 当pointSum==3的时候终止条件,对函数的值进行返回操作;其他更加复杂的不需要进行考虑,
vector<string> result;
void backtracking(s,startIndex,pointSum) // startIndex:确定下一层循环从字符串的那边开始取值;pointSum通过逗点的数量决定树的深度
// 如果有三个逗点,四个字符串就可以返回这个子字符串
if(pointSum == 3){
if(isValid(s,startIndex,s.size-1)){//用来判断这个子串是否和合法,最后一段合法那么收集这个结果
result.popback(s)
return
}
}
for(i=startIndex,i<=s.size,i++){
// 切割之后对切割的子串进行合法性判断,区间是本题的难点所在
if(isValid(s,startIndex,i)){
// 合法性的判断完成之后,需要进行插入的操作
path
pointSum += 1
backtracking(s,i+2,pointSum) // 给字符串加了逗点所以需要记性i+2
s.erase
pointSum -= 1
}
}
class Solution:
def __init__(self):
self.result = []
self.path = []
def isValid(self,s,left,right):
if (int(s[left:right]) <= 255 and int(s[left:right]) >= 0 and s[left] != '0') or (s[left:right] == '0') :
return True
return False
def restoreIpAddresses(self, s: str) -> List[str]:
# 类似于回文子串,对字符串进行分割
def backtracking(startIndex):
# 终止条件时逗点为3时候的值
if startIndex == len(s) and len(self.path) == 4:
self.result.append('.'.join(self.path.copy()))
return
for i in range(startIndex,len(s)):
if len(self.path) > 3:
break
if self.isValid(s,startIndex,i+1):
print(self.path,startIndex,i+1)
self.path.append(s[startIndex:i+1])
backtracking(i+1)
self.path.pop()
backtracking(0)
return self.result
78.子集
- 子集问题和组合问题的不同之处,组合和分割字符串都是在终止条件处收集结果,但是子集问题每一层递归得到的结果都要放在结果集中。
path
result
void backtracking(nums,startIndex){
result.append(path) // 因为每一次递归都需要将当前结果存储进入result数组中
// 叶子结点的剩余数组都是空的状态,整体的叶子结点的情况
if(startIndex >= nums.size){
return
}
for(i=startIndex;i<nums.size;i++){
path.pushback(nums[])
backtracking(nums,i+1)
path.pop.back()
}
}
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
result = []
path = []
def backtracking(startIndex):
result.append(path.copy())
if startIndex >= len(nums):
return
for i in range(startIndex,len(nums)):
path.append(nums[i])
backtracking(i+1)
path.pop()
backtracking(0)
return result
90.子集II
同一个树枝上可以重复选2,同一个树层上不可以重复选2
class Solution:
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
result = []
path = []
nums = sorted(nums)
def backtracking(startIndex):
if startIndex > len(nums):
return
result.append(path.copy())
for i in range(startIndex,len(nums)):
# for循环决定树层的结构,树层维度上不要有相同的值即可。
if i > startIndex and nums[i] == nums[i-1]:
continue
path.append(nums[i])
backtracking(i+1)
path.pop()
backtracking(0)
return result