算法训练营day24 回溯算法③ 93.复原IP地址 、78.子集、 90.子集II

        今天继续回溯算法的专题,第三篇博客!

93.复原IP地址

输入:s = "25525511135"
输出:["255.255.11.135","255.255.111.35"]

        切割字符串为4段,当进行到第四段的时候对第四段字符串进行判断,是否可以输出到result数组中,优化:通过检查剩余位数来进行剪枝

回溯过程

  • 递归参数

        startIndex一定是需要的,因为不能重复分割,记录下一层递归分割的起始位置。本题我们还需要一个变量pointNum,记录添加逗点的数量。(记录已经是多少段了)

  • 递归终止条件

        本题明确要求只会分成4段,所以不能用切割线切到最后作为终止条件,而是分割的段数作为终止条件。pointNum表示逗点数量,pointNum为3说明字符串分成了4段了。然后验证一下第四段是否合法,如果合法就加入到结果集里

  • 单层搜索的逻辑

        在for (int i = startIndex; i < s.size(); i++)循环中 [startIndex, i] 这个区间就是截取的子串,需要判断这个子串是否合法。

  • 如果合法就在字符串后面加上符号.表示已经分割。
  • 如果不合法就结束本层循环,如图中剪掉的分支:

        然后就是递归和回溯的过程:递归调用时,下一层递归的startIndex要从i+1开始,同时记录分割符的数量pointNum 要 +1。回溯的时候,就将刚刚加入的分隔符. 删掉就可以了,pointNum也要-1。

判断子串是否合法

主要考虑到如下三点:

  • 段位以0为开头的数字不合法
  • 段位里有非正整数字符不合法
  • 段位如果大于255了不合法

回溯模版

void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {处理节点;backtracking(路径,选择列表); // 递归回溯,撤销处理结果}
}

代码实现

class Solution:def restoreIpAddresses(self, s: str) -> List[str]:result = []self.backtracking(s, 0, 0, '', result)return resultdef backtracking(self, s, start_index, point_num, current, result):# start_index: 标注下一层的循环开始位置# point_num: 切割逗点数量# current: 单个字符串保存# result: 结果数组集合存储if point_num == 3: #分割结束if self.is_valid(s, start_index, len(s) - 1):# 符合左闭右闭, 数组索引方式current += s[start_index: ]# 添加最后一段字符串result.append(current)return for i in range(start_index, len(s)):# range函数左闭右开# 判断该段字符是否符合, 如果不符合停止该层递归if self.is_valid(s, start_index, i): # 理解i的作用片段, 符合要求sub = s[start_index:i+ 1] # 切片左闭右开self.backtracking(s, i + 1, point_num + 1, current + sub + '.', result)# 理解python中的引用复制和复制赋值!else:breakdef is_valid(self, s, start, end):# 左闭右闭if start > end:return Falseif s[start] == '0' and start != end:# 开头数字为0return Falsenum = 0for i in range(start, end + 1):if not s[i].isdigit():return False # 判断是否遇到非数字字符num = num * 10 + int(s[i])if num > 255:return Falsereturn True

版本2(了解即可)

class Solution:def restoreIpAddresses(self, s: str) -> List[str]:results = []self.backtracking(s, 0, [], results)return resultsdef backtracking(self, s, index, path, results):if index == len(s) and len(path) == 4:results.append('.'.join(path))returnif len(path) > 4:  # 剪枝returnfor i in range(index, min(index + 3, len(s))):if self.is_valid(s, index, i):sub = s[index:i+1]path.append(sub)self.backtracking(s, i+1, path, results)path.pop()def is_valid(self, s, start, end):if start > end:return Falseif s[start] == '0' and start != end:  # 0开头的数字不合法return Falsenum = int(s[start:end+1])return 0 <= num <= 255

78.子集

        简单题目,属于组合范畴(普通模版级别),大家可以自己画一画树状图

回溯过程

  • 递归函数参数

        全局变量数组path为子集收集元素,二维数组result存放子集组合。(也可以放到递归函数参数里)递归函数参数在上面讲到了,需要startIndex。

  • 递归终止条件

        所剩集合为空的时候,就是叶子节点。那么什么时候剩余集合为空呢?就是startIndex已经大于数组的长度了,就终止了,因为没有元素可取了

  • 单层搜索逻辑

        求取子集问题,不需要任何剪枝!因为子集就是要遍历整棵树

class Solution:def subsets(self, nums: List[int]) -> List[List[int]]:result = []path = []self.backtracking(nums, 0, path, result)return resultdef 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()

90.子集II

        整数数组 nums ,其中可能包含重复元素,这个是困难的,所以要去重

        之前我们也做过一道去重的题目,更具体的说,这个就是“树枝去重”和“树层去重”的区别,毫无疑问,我们这道题仍然是树层去重,即树枝上存在相同元素是允许的,而书层上出现相同元素是不被允许的

        整体思路如下:是和之前“去重”思路完全一样的题目

代码实现(增加去重)

class Solution:def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:result = []path = []nums.sort()# 注意排序,这样相同的数字才可以放在一起,方便后续处理self.backtracking(nums, 0, path, result)return resultdef backtracking(self, nums, startIndex, path, result):result.append(path[:])for i in range(startIndex, len(nums)):if i > startIndex and nums[i] == nums[i - 1]: # 第一个遇到不要处理continuepath.append(nums[i])self.backtracking(nums, i + 1, path, result)path.pop()

代码实现(利用used数组)

class Solution:def subsetsWithDup(self, nums):result = []path = []used = [False] * len(nums)nums.sort()  # 去重需要排序self.backtracking(nums, 0, used, path, result)return resultdef backtracking(self, nums, startIndex, used, path, result):result.append(path[:])  # 收集子集for i in range(startIndex, len(nums)):# used[i - 1] == True,说明同一树枝 nums[i - 1] 使用过# used[i - 1] == False,说明同一树层 nums[i - 1] 使用过# 而我们要对同一树层使用过的元素进行跳过if i > 0 and nums[i] == nums[i - 1] and not used[i - 1]:continuepath.append(nums[i])used[i] = Trueself.backtracking(nums, i + 1, used, path, result)used[i] = Falsepath.pop()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/89647.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/89647.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jeccg-boot框架实现xls模板导出功能

文章目录一、后端部分二、前端部分三、模板制作一、后端部分 //1、在application-dev.yml文件增加模板路径path :#模板路径saxls: /data/opt/saxls/ //2、控制层写法 public class sabassalController extends JeecgController<sabassalVo, IsabassalService> {Autowired…

LangChain4j入门:Java开发者的AI应用开发指南

&#x1f680; 在AI浪潮席卷全球的今天&#xff0c;Java开发者如何快速上手大语言模型应用开发&#xff1f;LangChain4j为我们提供了完美的解决方案&#xff01; 前言&#xff1a;为什么Java开发者需要LangChain4j&#xff1f; 想象一下&#xff0c;你正在开发一个企业级应用&…

相机光学(五十)——Depth AF

1.什么是Depth AFDepth AF&#xff08;景深自动对焦&#xff09;&#xff0c;也称为 Depth-of-Field AF&#xff08;景深对焦&#xff09; 或 DEP AF&#xff0c;是一种基于景深范围的自动对焦技术&#xff0c;核心目标是&#xff1a;确保从前景到背景的一整段距离都在清晰景深…

Unity 堆栈分析实战指南 C#

Unity 堆栈分析实战指南 提示&#xff1a;内容纯个人编写&#xff0c;欢迎评论点赞&#xff0c;来指正我。 文章目录Unity 堆栈分析实战指南1. 前言2. 什么是堆栈3. Unity 中的堆栈4. 堆栈分析工具5. 如何进行堆栈分析6. 实战案例分析案例 1: 性能瓶颈分析案例 2: 内存泄漏检测…

AE MDX L6 L12 L18 电源手侧操作使用说明

AE MDX L6 L12 L18 电源手侧操作使用说明

Gemini Function Calling 和 Qwen3 Embedding和ReRanker模型

Gemini API 的函数调用&#xff08;Function Calling&#xff09;功能。它解决了传统大语言模型&#xff08;LLM&#xff09;的一个关键局限&#xff1a;LLM 本身是基于训练数据的“知识库”&#xff0c;擅长生成文本和回答问题&#xff0c;但无法直接执行代码、访问实时数据或…

​​VMware Workstation Pro 17.5.0 安装教程 - 详细步骤图解(附下载+激活)​

VMware Workstation Pro 17.5.0 是一款功能强大的虚拟机软件&#xff0c;允许用户在一台计算机上同时运行多个操作系统&#xff08;如 Windows、Linux、macOS&#xff09;&#xff0c;适用于开发、测试、运维及学习环境搭建。本教程提供 ​​详细安装步骤​​&#xff0c;包括 …

端到端神经网络视频编解码器介绍

一、技术演进&#xff1a;从模块优化到全局智能的范式跃迁 传统编解码器的效率天花板&#xff08;1990-2017&#xff09; 架构局限&#xff1a;H.264/HEVC依赖手工设计的运动估计、DCT变换、熵编码模块&#xff0c;各模块独立优化导致全局效率损失。高分辨率瓶颈&#xff1a;4…

Kubernetes (k8s)环境重启Pod方式总结

前言&#xff1a;在 Kubernetes (k8s) 中&#xff0c;没有直接的命令如 kubectl restart pod 来重启 Pod&#xff0c;因为 Pod 的生命周期由控制器&#xff08;如 Deployments、StatefulSets 或 ReplicaSets&#xff09;管理。重启操作本质上是通过删除并重建 Pod 来实现的&…

OOA、OOD 与 OOP:面向对象范式的核心支柱详解

作为软件系统架构的核心范式&#xff0c;面向对象方法贯穿软件开发生命周期。OOA、OOD 和 OOP 分别代表分析、设计和实现三个关键阶段&#xff0c;共同构成一个连贯的工程体系。一、OOA (Object-Oriented Analysis&#xff0c;面向对象分析) 目标&#xff1a;理解问题域&#x…

GBase 8a 与 Spring Boot + MyBatis 整合实战:从环境搭建到CRUD操作

一、引言 在企业级数据管理场景中&#xff0c;GBase数据库凭借其高性能的数据分析能力和对SQL标准的良好兼容性&#xff0c;成为金融、电信等行业的常用选择。本文将详细演示如何将GBase数据库与Spring Boot、MyBatis框架整合&#xff0c;实现高效的数据持久化操作&#xff0c…

功能安全之BIST的基本原理

BIST&#xff08;Built-In Self-Test&#xff0c;内建自测试&#xff09;是一种将测试功能直接集成到集成电路&#xff08;IC&#xff09;或系统内部的设计方法。其基本原理的核心在于&#xff1a;让被测试电路自身&#xff08;或借助少量专用硬件&#xff09;来生成测试激励、…

Linux 程序地址空间

目录 Ⅰ、什么是程序地址空间&#xff1f; Ⅱ、虚拟地址空间是什么样的&#xff1f; 一、虚拟地址空间和页表 1、什么是页表&#xff1f; 2、什么是虚拟地址空间&#xff1f; 3、什么是vm_area_struct? Ⅲ、为什么要用虚拟地址空间&#xff1f; 一、进程的独立性 二、…

【iOS】消息传递和消息转发

文章目录前言一、消息传递&#xff1a;objc_msgSend 的“查字典递归找家长”流程1. 第一步&#xff1a;查“最近调用记录”&#xff08;方法缓存&#xff09;—— 最快即快速查找&#xff01;2. 第二步&#xff1a;翻“自己的字典”&#xff08;类方法列表查找&#xff09;——…

MySQL查询优化与事务实战指南

本节用到的员工信息管理表结构放到资源中&#xff0c;需要的同学自取。本节内容以此表为示例&#xff1a; 面试题&#xff1a;innodb与myisam的区别。 外键&#xff0c;事务 特性InnoDBMyISAM事务支持支持不支持外键支持不支持锁粒度行级锁表级锁索引结构聚簇索引非聚簇索引崩…

Windows 10/11 磁盘清理操作指南:彻底解决系统盘空间不足问题

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#,Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开发…

b-up:Enzo_Mi:深度学习基础知识

1.最近邻差值&#xff08;Neareast Neighbor Interpolation&#xff09; 插值算法 &#xff5c; 最近邻插值法_哔哩哔哩_bilibili 上图中最后一行&#xff0c;第一个图像&#xff0c;因为目标像素&#xff08;放大后&#xff0c;位于第1行第0列的像素&#xff09;距离它最近的…

微信小程序商品结算功能

整体结算流程概述微信小程序的商品结算涉及前端交互、API调用和数据管理。典型流程包括&#xff1a;用户交互&#xff1a;用户选择商品、填写地址和时间。数据获取&#xff1a;从小程序缓存或后端服务器获取订单信息。逻辑处理&#xff1a;验证参数、应用红包折扣。提交订单&am…

2025年7月份最新一区算法——向光生长算法

注&#xff1a;该算法已按照智能优化算法APP标准格式进行整改&#xff0c;可直接集成到APP中&#xff0c;方便大家与自己的算法进行对比。&#xff08;近期智能优化算法APP将会迎来超级大更新&#xff01;请时刻保持关注哦&#xff01;&#xff09;向光生长算法&#xff08;Pho…

脚手架新建Vue2/Vue3项目时,项目文件内容的区别

一. package.json vue版本号不同vue2中会多一个依赖&#xff1a;vue-template-compiler&#xff0c;作用是预编译Vue2模板为渲染函数&#xff0c;减少运行时开销。vue-template-compiler与vue版本要保持一致&#xff0c;否则会报错。eslintConfig中的extends不同 eslintConfig…