day30【代码随想录】回溯之分割回文串、复原IP地址、子集
创始人
2024-05-02 14:24:39
0

文章目录

  • 前言
  • 一、分割回文串(力扣131)
  • 二、复原IP地址(力扣93)
  • 三、子集(力扣78)
  • 总结


前言

1、分割回文串
2、复原IP地址
3、子集


一、分割回文串(力扣131)

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。

回文串 是正着读和反着读都一样的字符串。
在这里插入图片描述
思路:
关键在于[startIndex,i] 这个区间就是我们切割的子串【重点!!!】
startIndex就相当于是切割线!!!
在这里插入图片描述
整体步骤:
1、如何模拟切割线
2、递归如何终止
3、如何获取子串
4、判断回文

class Solution {List> res = new ArrayList<>();LinkedList paths = new LinkedList<>();public List> partition(String s) {backtracking(s,0);return res;}public void backtracking(String s,int startIndex){if(startIndex==s.length()){res.add(new ArrayList<>(paths));return ;}for(int i=startIndex;iif(isPalinderome(s,startIndex,i)){String str = s.substring(startIndex,i+1);paths.add(str);}else{continue;}backtracking(s,i+1);paths.removeLast();//回溯}}public boolean isPalinderome(String s,int start,int end){for(int i=start,j=end;iif(s.charAt(i)!=s.charAt(j)){return false;}}return true;}
}

在这里插入图片描述

二、复原IP地址(力扣93)

有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 ‘.’ 分隔。

  • 例如:“0.1.2.201” 和 “192.168.1.1” 是 有效 IP 地址,但是 “0.011.255.245”、“192.168.1.312” 和 “192.168@1.1” 是 无效 IP 地址。

给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 ‘.’ 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。

在这里插入图片描述
思路:
在这里插入图片描述
与切割回文串类似:
关键在于切割 切割出来的子串区间 [stratIndex,i] 以及一些字符串的拼接操作,增加"." 判断子串是否合法等等

结束判断:
1、“.”逗点数量已经==3时,需要判断最后一段截取的子串是否合法,如果合法,收集结果

字符串拼接:
1、如果当前截取的子串合法
2、拼接子串(加“.”)
3、递归 (细节:参数不再是i+1 而是i+2)
4、回溯(子串也要退回之前的状态 把“.”去掉)

判断子串是否合法:
1、两位数及以上时 第一位如果为0 不合法
2、包含除0-9以外的其他字符 不合法
3、数值大于255 不合法

class Solution {List res = new ArrayList<>();public List restoreIpAddresses(String s) {if(s.length()>12) return res;backtracking(s,0,0);return res;}public void backtracking(String s,int startIndex,int pointSum){ if(pointSum==3){//判断最后一个部分是不是合法if(isValid(s,startIndex,s.length()-1)){//左闭右闭区间//加入结果集    res.add(s);}return ;}for(int i=startIndex;i//判断所截取子串是否合法if(isValid(s,startIndex,i)){s=s.substring(0,i+1)+"."+s.substring(i+1);//插入逗号pointSum++;backtracking(s,i+2,pointSum);pointSum--;//删除逗号s=s.substring(0,i+1)+s.substring(i+2);}else{continue;}}}public boolean isValid(String s,int start,int end){if(start>end){return false;}if(s.charAt(start)=='0'&& start!=end){return false;}int num=0;for(int i=start;i<=end;i++){if(s.charAt(i)>'9' || s.charAt(i)<'0'){return false;}num = num*10+(s.charAt(i)-'0');if(num>255)return false;}return true;}
}

在这里插入图片描述

三、子集(力扣78)

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

在这里插入图片描述
以示例中nums = [1,2,3]为例把求子集抽象为树型结构,如下:
在这里插入图片描述
求取子集问题,不需要任何剪枝!因为子集就是要遍历整棵树。
遍历这个树的时候,把所有节点都记录下来,就是要求的子集集合。

class Solution {List> res = new ArrayList<>();LinkedList paths = new LinkedList<>();public List> subsets(int[] nums) {backtracking(nums,0);return res;}public void backtracking(int[] nums,int startIndex){res.add(new ArrayList<>(paths)); //遍历这棵树的时候,把所有结点记录下来if(startIndex==nums.length){return ;}for(int i=startIndex;ipaths.add(nums[i]);backtracking(nums,i+1);paths.removeLast();}}
}

在这里插入图片描述


总结

如果把 子集问题、组合问题、分割问题都抽象为一棵树的话,那么组合问题和分割问题都是收集树的叶子节点,而子集问题是找树的所有节点!

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...