代码学习记录23--回溯算法第四天

随想录日记part23

t i m e : time: time 2024.03.19



主要内容:回溯算法在代码学习中尤其重要,所以今天继续加深对其的理解:1:复原IP地址 ;2.子集 ;3.子集II

  • 93.复原IP地址
  • 78.子集
  • 90.子集II


Topic1复原IP地址

题目:

有效 IP 地址正好由四个整数(每个整数位于 0 0 0 255 255 255 之间组成,且不能含有前导 0 0 0),整数之间用 ‘.’ 分隔。例如: " 0.1.2.201 " "0.1.2.201" "0.1.2.201" " 192.168.1.1 " "192.168.1.1" "192.168.1.1" 是 有效 IP 地址,但是 " 0.011.255.245 " 、 " 192.168.1.312 " "0.011.255.245"、"192.168.1.312" "0.011.255.245""192.168.1.312" " 192.168 @ 1.1 " "192.168@1.1" "192.168@1.1" 是 无效 I P IP IP 地址。
给定一个只包含数字的字符串 s s s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s s s 中插入 ‘.’ 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。

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

思路:

切割问题,切割问题就可以使用回溯搜索法把所有可能性搜出来
按照回溯模板我们进行回溯三部曲:
递归三部曲:
1.回溯函数模板返回值以及参数
在这里要定义一个全局变量 r e s u l t result result用来存放符合条件结果的集合。回溯函数里需要一个参数为 i n t int int 型变量 s t a r t I n d e x startIndex startIndex,来表示切割字符的起始索引,同时还需要一个 i n t int int 类型的变量 n u m P o i n t numPoint numPoint 来记录切割点数。
所以整体代码如下:

List<String> result = new LinkedList<>();// 保存最后结果的数组void reback(String s, int startIndex, int numPoint)

2.回溯函数终止条件
本题明确要求只会分成 4 4 4 段,所以不能用切割线切到最后作为终止条件,而是分割的段数作为终止条件。 n u m P o i n t numPoint numPoint 表示逗点数量, n u m P o i n t numPoint numPoint 3 3 3 说明字符串分成了 4 4 4 段了。然后验证一下第四段是否合法,如果合法就加入到结果集里
代码如下:

if (numPoint == 3) {if (isVaid(s, startIndex, s.length() - 1))result.add(s);elsereturn;}

3.回溯搜索的遍历过程
f o r ( i n t i = s t a r t I n d e x ; i < s . s i z e ( ) ; i + + ) for\ (int\ i = startIndex; i < s.size(); i++) for (int i=startIndex;i<s.size();i++)循环中 [ s t a r t I n d e x , i ] [startIndex, i] [startIndex,i] 这个区间就是截取的子串,需要判断这个子串是否合法。如果合法就在字符串后面加上符号 . . . 表示已经分割。
如果不合法就结束本层循环,如图中剪掉的分支:
在这里插入图片描述
然后就是递归和回溯的过程:
递归调用时下一层递归的 s t a r t I n d e x startIndex startIndex 要从 i + 2 i+2 i+2开始(因为需要在字符串中加入了分隔符 . . . ),同时记录分割符的数量 n u m P o i n t numPoint numPoint + 1 +1 +1
回溯的时候,就将刚刚加入的分隔符. 删掉就可以了, n u m P o i n t numPoint numPoint也要 − 1 -1 1
实现代码如下:

for (int i = startIndex; i < s.length(); i++) {if (isVaid(s, startIndex, i)) {s = s.substring(0, i + 1) + "." + s.substring(i + 1);numPoint++;reback(s, i + 2, numPoint);numPoint--;// 回溯s = s.substring(0, i + 1) + s.substring(i + 2);// 回溯} else {break;// 这里注意思考为啥不用return或者continue}

完整的代码如下:

class Solution {List<String> result = new LinkedList<>();// 保存最后结果的数组public List<String> restoreIpAddresses(String s) {if (s.length() > 12)return result;reback(s, 0, 0);return result;}private void reback(String s, int startIndex, int numPoint) {if (numPoint == 3) {if (isVaid(s, startIndex, s.length() - 1))result.add(s);elsereturn;}for (int i = startIndex; i < s.length(); i++) {if (isVaid(s, startIndex, i)) {s = s.substring(0, i + 1) + "." + s.substring(i + 1);numPoint++;reback(s, i + 2, numPoint);numPoint--;// 回溯s = s.substring(0, i + 1) + s.substring(i + 2);// 回溯} else {break;// 这里注意思考为啥不用return或者continue}}}private Boolean isVaid(String s, int begin, int end) {// 判断字符是否合法if (end < begin)return false;if (s.charAt(begin) == '0' && begin != end)return false;int count = 0;// 计算器for (int i = begin; i <= end; i++) {if (s.charAt(i) < '0' || s.charAt(i) > '9')return false;count = count * 10 + s.charAt(i) - '0';}if (count > 255)return false;elsereturn true;}
}

时间复杂度: O ( 3 4 ) O(3^4) O(34),IP地址最多包含4个数字,每个数字最多有3种可能的分割方式,则搜索树的最大深度为4,每个节点最多有3个子节点。
空间复杂度: O ( n ) O(n) O(n)



Topic2子集

题目:

给你一个整数数组 n u m s nums nums ,数组中的元素互不相同 。返回该数组所有可能的子集(幂集)。解集不能包含重复的子集。你可以按任意顺序返回解集。

输入: n u m s = [ 1 , 2 , 3 ] nums = [1,2,3] nums=[1,2,3]
输出: [ [ ] , [ 1 ] , [ 2 ] , [ 1 , 2 ] , [ 3 ] , [ 1 , 3 ] , [ 2 , 3 ] , [ 1 , 2 , 3 ] ] [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]] [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

思路:

如果把子集问题、组合问题、分割问题都抽象为一棵树的话,那么组合问题和分割问题都是收集树的叶子节点,而子集问题是找树的所有节点!以示例中 n u m s = [ 1 , 2 , 3 ] nums = [1,2,3] nums=[1,2,3] 为例把求子集抽象为树型结构,如下:
在这里插入图片描述
从图中红线部分,可以看出遍历这个树的时候,把所有节点都记录下来,就是要求的子集集合。
按照回溯模板我们进行回溯三部曲:
递归三部曲:
1.回溯函数模板返回值以及参数
在这里要定义两个全局变量, p a t h path path用来存放符合条件单一结果, r e s u l t result result用来存放符合条件结果的集合。回溯函数里需要一个参数为 i n t int int 型变量 s t a r t I n d e x startIndex startIndex
所以整体代码如下:

List<List<Integer>> result=new ArrayList<>();
LinkedList<Integer> path=new LinkedList<>();
void reback(int[] nums,int startIndex)

2.回溯函数终止条件
就是 s t a r t I n d e x startIndex startIndex 已经大于数组的长度了,就终止了,因为没有元素可取了,代码如下:
代码如下:

if(startIndex>=nums.length) {return; }

3.回溯搜索的遍历过程
求取子集问题,不需要任何剪枝!因为子集就是要遍历整棵树。

实现代码如下:

 for(int i=startIndex;i<nums.length;i++){path.add(nums[i]);reback(nums,i+1);path.removeLast();}

完整的代码如下:

class Solution {List<List<Integer>> result=new ArrayList<>();//记录最后的结果List<Integer> path=new LinkedList<>();public List<List<Integer>> subsets(int[] nums) {reback(nums,0);return result;}private void reback(int[] nums,int startIndex){result.add(new ArrayList(path));if(startIndex>=nums.length) {return; }for(int i=startIndex;i<nums.length;i++){path.add(nums[i]);reback(nums,i+1);path.removeLast();}}
}

时间复杂度: O ( n ∗ 2 n ) O(n * 2^n) O(n2n)
空间复杂度: O ( n ) O(n) O(n)



Topic3子集II

题目:

给你一个整数数组 n u m s nums nums ,其中可能包含重复元素,请你返回该数组所有可能的 子集(幂集)。解集不能包含重复的子集。返回的解集中,子集可以按任意顺序排列。

输入: n u m s = [ 1 , 2 , 2 ] nums = [1,2,2] nums=[1,2,2]
输出: [ [ ] , [ 1 ] , [ 1 , 2 ] , [ 1 , 2 , 2 ] , [ 2 ] , [ 2 , 2 ] ] [[],[1],[1,2],[1,2,2],[2],[2,2]] [[],[1],[1,2],[1,2,2],[2],[2,2]]

思路:
这个就是上面的方法加上了去重操作,去重的两种方法和之前如出一辙,下面直接给出两种代码:

1.使用used数组的

class Solution {List<List<Integer>> result=new ArrayList<>();LinkedList<Integer> path=new LinkedList<>();boolean[] used;public List<List<Integer>> subsetsWithDup(int[] nums) {Arrays.sort(nums);used=new boolean[nums.length];reback(nums,0);return result;}private void reback(int[] nums,int startIndex){result.add(new ArrayList(path));if(startIndex>=nums.length) {return; }for(int i=startIndex;i<nums.length;i++){if(i>0 && nums[i]==nums[i-1] && !used[i-1]){continue;}path.add(nums[i]);used[i]=true;reback(nums,i+1);path.removeLast();used[i]=false;}}
}

2.不使用used数组的

class Solution {List<List<Integer>> result=new ArrayList<>();LinkedList<Integer> path=new LinkedList<>();public List<List<Integer>> subsetsWithDup(int[] nums) {Arrays.sort(nums);reback(nums,0);return result;}private void reback(int[] nums,int startIndex){result.add(new ArrayList(path));if(startIndex>=nums.length) {return; }for(int i=startIndex;i<nums.length;i++){if(i>startIndex && nums[i]==nums[i-1]){continue;}path.add(nums[i]);reback(nums,i+1);path.removeLast();}}
}

时间复杂度: O ( n ∗ 2 n ) O(n * 2^n) O(n2n)
空间复杂度: O ( n ) O(n) O(n)

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

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

相关文章

shopee无货源出单了怎么发货?shopee怎么做无货源?

在Shopee的电商大舞台上&#xff0c;“无货源出单”就像是一场神奇的魔术表演。你的店铺是舞台&#xff0c;买家的订单是观众的掌声&#xff0c;而你&#xff0c;就是那位神秘的魔术师。订单来了&#xff0c;你却没有货&#xff1f;这可不是什么障碍&#xff0c;因为你有着更为…

前端学习从0到1:再见HTML(1)

阅读须知&#xff1a; 探索者安全团队技术文章仅供参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作,由于传播、利用本公众号所提供的技术和信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者 本人负责&#xff0c;作者不为此承担任何责任,如…

AI系统性学习05—向量数据库

文章目录 1、Chroma向量数据库1.1 安装Chroma1.2 初始化Chroma客户端1.3 创建一个合集1.4 添加数据1.5 查询数据1.6 持久化数据1.7 集合操作1.7.1 创建集合1.7.2 获取集合1.7.3 删除集合1.7.4 其他操作1.8 向集合添加数据1.9 查询集合数据1.10 更新集合数据1.11 删除集合数据1.…

JavaSE(上)-Day5

JavaSE&#xff08;上&#xff09;-Day5 流程控制语句顺序结构分支结构循环结构 流程控制语句练习逢7过题目平方根质数判断随机数猜测 流程控制语句 顺序结构 Java代码执行是自上而下的顺序结构 分支结构 if分支(已掌握) &#xff08;多应用范围&#xff09;switch分支(有限…

基于51单片机智能鱼缸控制系统

一、系统方案 1、本设计采用51单片机作为主控器。 2、液晶1602显示。 3、采集温度值&#xff0c;水质大小、水位值、DS1302显示年月日时分秒。 4、自动加热、定时喂食&#xff0c;自动换水、水泵加热。 5、按键设置。 二、硬件设计 原理图如下&#xff1a; 三、单片机软件设…

【教学类-44-08】20240319 “(幼儿用)数字练习簿1.0”(A4版)

背景需求&#xff1a; 我一直想把 “&#xff08;幼儿用&#xff09;数字练习簿”的内容复刻出来——这里面的字体始终找不到&#xff0c;是一种已经做成图片的手写数字字体 素材准备&#xff1a; 1、买了一本&#xff08;幼儿用&#xff09;数字练习簿&#xff0c;把每一页扫…

java 通过 microsoft graph 调用outlook(二)

这次提供一些基础调用方式API 一 POM文件 <!-- office 365 --><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>32.1.3-jre</version></dependency><dependency>&…

网络编程:多点通信+域套接字

一、多点通信 1.网络属性 getsockopt和setsockopt int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen); int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); 功能&#xff1a;获取或设置套接字…

微信小程序登录后根据code获取APP_ID和APP_SECRET与火狐信息

话不多说&#xff0c;直接上代码。 session_key是与用户微信客户端之间通信的密钥&#xff0c;获取用户信息时会用到。 调用&#xff1a;getSessionKeyAndOpenId方法传入code值&#xff0c;返回openid与session_key&#xff0c; 这里的&#xff1a; appid: 应用唯一标识&am…

SSH服务

目录 一. 熟悉SSH服务 1.1 何为SSH协议 1.2 SSH服务优点 1.3 常见的SSH协议 1.4 SSH服务的功能 1.5 为何使用SSH服务 1.6 SSH服务的工作原理 1.6.1 公钥传输原理 1.6.2 ssh加密通讯原理 1.7 SSH服务的最佳应用场景 1.8 SSH服务远程登录的方式 1.8.1 方法一&#…

自动驾驶决策 - 规划 - 控制 (持续更新!!!)

总目录 Frenet与Cartesian坐标系 Apollo基础 - Frenet坐标系 车辆模型 车辆运动学和动力学模型 控制算法 PID控制器轨迹跟随实现 Pure Pursuit控制器路径跟随 路径跟踪算法Stanley 实现 c 无人驾驶LQR控制算法 c 实现 MPC自动驾驶横向控制算法实现 c 双环PID控制详细讲解 …

【DL经典回顾】激活函数大汇总(二十六)(Identity附代码和详细公式)

激活函数大汇总&#xff08;二十六&#xff09;&#xff08;Identity附代码和详细公式&#xff09; 更多激活函数见激活函数大汇总列表 一、引言 欢迎来到我们深入探索神经网络核心组成部分——激活函数的系列博客。在人工智能的世界里&#xff0c;激活函数扮演着不可或缺的…

大模型面试题最全总结,没有一道是送分题。。。

节前&#xff0c;我们组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂同学、参加社招和校招面试的同学&#xff0c;针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 今天分享…

3月19日做题

[NPUCTF2020]验证&#x1f40e; if (first && second && first.length second.length && first!second && md5(firstkeys[0]) md5(secondkeys[0]))用数组绕过first1&second[1] 这里正则规律过滤位(Math.) (?:Math(?:\.\w)?) : 匹配 …

串口123

1.开启时钟 把需要使用的USART和GPIO的时钟打开 2.GPIO初始化 把TX配置成复用输出&#xff0c;RX配置成输入 3.配置USART 直接使用一个结构体即可将所有参数配置完成 4.开关控制 如果需要仅发送的功能&#xff0c;就直接开启USART&#xff0c;初始化到此结束 如果还需要接收…

优化器算法SGD、Adam、AdamW等

文章目录 SGDSGD with momentumSGD with Nesterov AccelerationAdaGradRMSpropAdaDeltaAdamAdamW参考资料 假设有&#xff1a; 待优化的目标函数为 f ( w ) f(w) f(w)&#xff0c;使用优化算法来最小化目标函数 f ( w ) : a r g m i n w f ( w ) f(w):argmin_wf(w) f(w):argmin…

获取指定路径下,所有指定后缀文件列表

要获取指定路径下所有指定后缀的文件列表&#xff0c;你可以使用Python的os和glob模块。下面是一个简单的示例&#xff0c;展示了如何获取指定路径下所有.txt后缀的文件列表&#xff1a; import os import globdef get_files_with_extension(directory, extension):"&quo…

vivado 布线、路线_设计

路由 Vivado路由器对放置的设计执行路由&#xff0c;并对路由设计&#xff0c;以解决保留时间冲突。Vivado路由器从放置的设计开始&#xff0c;并尝试路由所有网络。它可以从已放置的未布线、部分布线或完全布线的设计。对于部分路由的设计&#xff0c;Vivado路由器使用现有的…

Unittest框架及自动化测试实现流程

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 Unittest框架介绍 Unittest框架是Python中一个标准的库中的一个模块&#xff0c;该模块包括许多…

红与黑(c++题解)

题目描述 有一间长方形的房子&#xff0c;地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上&#xff0c;只能向相邻的黑色瓷砖移动。请写一个程序&#xff0c;计算你总共能够到达多少块黑色的瓷砖。 输入格式 包括多个数据集合。每个数据集合的第一行是…