当前位置: 首页 > news >正文

代码随想录第21天: 回溯算法3

一、复原IP地址(Leetcode 93 )

1.确定递归函数参数:

def backtracking(self, s, start_index, point_num, current, result):

2.递归终止条件:

         if point_num == 3:  # 逗点数量为3时,分隔结束if self.is_valid(s, start_index, len(s) - 1):  # 判断第四段子字符串是否合法current += s[start_index:]  # 添加最后一段子字符串result.append(current)return

3.单层递归逻辑:

        for i in range(start_index, len(s)):# 判断 [start_index, i] 这个区间的子串是否合法if self.is_valid(s, start_index, i):  sub = s[start_index:i + 1]self.backtracking(s, i + 1, point_num + 1, current + sub + '.', result)else:break

完整代码:

class Solution:def restoreIpAddresses(self, s: str) -> List[str]:result = []  # 存储最终结果self.backtracking(s, 0, 0, "", result)  # 从索引0开始递归,初始点数量为0return resultdef backtracking(self, s, start_index, point_num, current, result):# 基准条件:当point_num为3时,说明已经分割了前三个部分if point_num == 3:# 检查剩余部分是否是合法的IP段if self.is_valid(s, start_index, len(s) - 1):current += s[start_index:]  # 加上最后一段子串result.append(current)  # 完成的IP地址加入结果return# 递归逻辑:横向遍历每一段子串,递归处理for i in range(start_index, len(s)):if self.is_valid(s, start_index, i):  # 检查子串是否合法sub = s[start_index:i + 1]  # 取出当前子串self.backtracking(s, i + 1, point_num + 1, current + sub + '.', result)  # 递归处理下一段else:break  # 如果当前子串不合法,跳出循环def is_valid(self, s, start, end):# 判断s[start:end+1]是否是合法的IP段if start > end:return Falseif s[start] == '0' and start != end:  # 0开头的多位数字不合法return Falsenum = 0for i in range(start, end + 1):if not s[i].isdigit():  # 非数字字符不合法return Falsenum = num * 10 + int(s[i])  # 累加形成数字if num > 255:  # 大于255不合法return Falsereturn True  # 合法

二、子集问题(Leetcode 78)

1.确定递归函数参数:

def backtracking(self, nums, startIndex, path, result):

2.递归终止条件:

没有终止条件,因为我们要搜集所有路径节点

3.单层递归逻辑:

        for i in range(startIndex, len(nums)):path.append(nums[i])self.backtracking(nums, i + 1, path, result)path.pop()

完整代码:

class Solution:def subsets(self, nums):result = []  # 存储所有子集的结果path = []  # 当前路径,存储一个子集self.backtracking(nums, 0, path, result)  # 从索引0开始递归return result  # 返回所有子集def backtracking(self, nums, startIndex, path, result):result.append(path[:])  # 每次递归时,都将当前路径加入到结果中# 遍历数组,生成所有可能的子集for i in range(startIndex, len(nums)):path.append(nums[i])  # 将当前元素加入路径self.backtracking(nums, i + 1, path, result)  # 递归生成下一个子集path.pop()  # 回溯,撤销选择,继续尝试其他元素

三、子集II(Leetcode  90)

回溯与去重: used 数组和判断 if i > 0 and nums[i] == nums[i - 1] and not used[i - 1]: continue 确保不会在同一树层使用重复元素,从而避免生成重复的子集。

class Solution:def subsetsWithDup(self, nums):result = []  # 存储所有子集path = []  # 当前路径,存储一个子集used = [False] * len(nums)  # 记录每个元素是否在当前递归中使用过nums.sort()  # 排序,确保重复元素相邻self.backtracking(nums, 0, used, path, result)  # 从索引0开始递归return result  # 返回所有子集def backtracking(self, nums, startIndex, used, path, result):result.append(path[:])  # 每次递归时都将当前路径加入到结果中# 遍历数组,生成所有可能的子集for i in range(startIndex, len(nums)):# 如果当前元素与前一个元素相同,且前一个元素在当前树层未使用过,跳过当前元素if i > 0 and nums[i] == nums[i - 1] and not used[i - 1]:continuepath.append(nums[i])  # 将当前元素加入路径used[i] = True  # 标记当前元素已使用self.backtracking(nums, i + 1, used, path, result)  # 递归生成下一个子集used[i] = False  # 回溯,撤销当前元素的选择path.pop()  # 回溯,移除路径中的当前元素

四、非递减子序列(Leetcode 491)

class Solution:def findSubsequences(self, nums):result = []  # 存储结果path = []  # 当前路径,存储一个递增子序列self.backtracking(nums, 0, path, result)  # 从索引0开始递归return result  # 返回所有递增子序列def backtracking(self, nums, startIndex, path, result):# 如果当前路径的长度大于1,说明这是一个有效的递增子序列if len(path) > 1:result.append(path[:])  # 将当前路径的副本加入结果中uset = set()  # 使用集合来去重,避免同一层递归中使用重复元素for i in range(startIndex, len(nums)):# 递增条件:当前元素小于路径最后一个元素则跳过# 或者当前元素已经在本层用过,跳过if (path and nums[i] < path[-1]) or nums[i] in uset:continueuset.add(nums[i])  # 记录当前元素在本层已经使用过path.append(nums[i])  # 将当前元素加入路径self.backtracking(nums, i + 1, path, result)  # 递归生成下一个子序列path.pop()  # 回溯,撤销当前选择

相关文章:

  • HAL库(STM32CubeMX)——高级ADC学习、HRTIM(STM32G474RBT6)
  • 策略模式:思考与解读
  • 版本控制利器——SVN简介
  • 浙江大学DeepSeek 公开课 第三季 第1期讲座 - 马东方教授 (附PPT下载) by突破信息差
  • 多线程出bug不知道如何调试?java线程几种常见状态
  • 《C/C++预定义宏深度剖析:编译上下文获取指南》
  • RSS 2025|苏黎世提出「LLM-MPC混合架构」增强自动驾驶,推理速度提升10.5倍!
  • unity打包安卓时的签名文件jks转换keystore
  • 欧拉-国产操作系统替代产品如何
  • 使用openssl为localhost创建自签名
  • 大模型AI的运行逻辑与准确性保障机制——以DeepSeek与豆包为例
  • K8s使用LIRA插件更新安全组交互流程
  • MMIO、IOMAP 和 IOMMU 总结
  • 一文了解相位阵列天线中的真时延
  • Vibracostic EDI 需求分析
  • 单例模式的使用场景 以及 饿汉式写法(智能指针)
  • LangChain、LlamaIndex 和 ChatGPT 的详细对比分析及总结表格
  • 【AI News | 20250421】每日AI进展
  • 如何将Qt程序打包成应用程序?
  • visionpro案例: 轴承缺珠检测
  • 民政部:从未设立或批准设立“一脉养老”“惠民工程”项目,有关App涉嫌诈骗
  • 宁波一季度GDP为4420.5亿元,同比增长5.6%
  • 著名政治学学者、中国人民大学教授仝志敏逝世
  • 海南医科大学继续开展部门正职竞聘上岗,致力营造“谁有本事谁来”
  • 深化应用型人才培养,这所高校聘任行业企业专家深度参与专业设置
  • 数智时代出版专业技能人才培养研讨会在沪举行