DFS回溯剪枝|KMP通过数组记录减少判断子字符串|思路

KMP|DFS回溯剪枝

#1、NC149kmp

在这里插入图片描述
初步思路:

两层for循环,一个T的字符开始与
S的字符比较,挨个比较,遇到不同就continue当前T的字符,重复步骤=》效率太低,超时

eg:
T=ABSABABABD
S=ABABD

S!=A时,退回到A与S比较,发现不同;
继续比较A与A,B与B…A与D,不相等了了。
此时,D前面有两个AB,所以指向S的字符索引只往前移动两个字符,退回到AB|(这里)ABD,即第一个AB公共前缀后面的A这里。
继续A与A比较…

KMP的核心思想是:不必退回到开始的地方!比较过的地方就不用重复比较了!
用一个数组去记录应该退回到哪里合适

next[j - 1] 表示在 S[0…j-1] 这个子字符串中,最长的相同前缀和后缀的长度。如果 S[j] 和当前要比较的字符不匹配,这意味着 S[j] 不能作为前缀的一部分,因此需要找到一个更短的前缀,使得 S[0…next[j-1]] 和 S[i…] 能够匹配。
while 循环用于在 next 数组构建过程中,当当前字符 S.charAt(i) 与 S.charAt(j) 不匹配时,回溯找到 j 的下一个有效值。这个值是 S[0…j-1] 的最长相同前缀和后缀的长度。
为什么 while 在 if 前面:

当 S.charAt(j) != S.charAt(i) 时,说明当前 j 所对应的前缀无法与 i 位置的字符匹配。此时,需要减小 j 的值,直到找到一个匹配的前缀或者 j 减到 0。

while 循环确保即使在多次不匹配的情况下,j 也能正确地回溯到一个有效的值。如果使用 if 语句,那么在 j > 0 且 S.charAt(j) != S.charAt(i) 时,j 只会减少 1,这可能不会找到正确的前缀匹配。

if 条件的作用:当 S.charAt(j) == S.charAt(i) 时,说明当前字符匹配,j 可以安全地向前移动一位,因为 S[0…j] 和 S[i…](从 i 开始的剩余字符串)有一个共同的字符可以匹配。

next[i] = j; 的意义:
无论 S.charAt(j) 和 S.charAt(i) 是否匹配,next[i] 都被设置为 j 的当前值。
如果字符匹配,j 已经增加了 1,next[i] 反映了这个增加;
如果字符不匹配,j 通过 while 循环回溯到了正确的值,next[i] 反映了这个回溯。

 public int[] getNext(String S) {int l = S.length();// 获得next数组int[] next = new int[l];next[0] = 0; //没有公共前缀int j = 0;// AABAS// 01for (int i = 1; i < l; i++) {while (j > 0 && S.charAt(j) != S.charAt(i)) {j = next[j - 1]; //会退一步判断// :next[j - 1] 表示在 S[0...j-1] 这个子字符串中,最长的相同前缀和后缀的长度。如果 S[j] 和当前要比较的字符不匹配,这意味着 S[j] 不能作为前缀的一部分,因此需要找到一个更短的前缀,使得 S[0...next[j-1]] 和 S[i...] 能够匹配。}if (S.charAt(j) == S.charAt(i)) {j++;}next[i] = j; //验证到了这一步了。}return next;}

通过相同的思路使用next[]数组,
先while退回到合适的索引位置(针对S而言)
然后是if判断,S的索引++;
如果S的索引走到了S的末尾,那么说明已在T中找到等于S 的字串。

 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** 计算模板串S在文本串T中出现了多少次* @param S string字符串 模板串* @param T string字符串 文本串* @return int整型*/public int kmp (String S, String T) {// write code hereint sl=S.length();int tl=T.length();int count=0;int[] next=getNext(S);int j=0;for(int i=0;i<tl;i++){while(j>0&&S.charAt(j)!=T.charAt(i)){j=next[j-1];}if(S.charAt(j)==T.charAt(i)){j++;}if(j==sl){count++;j=next[j-1];//会退回去继续判断}}return  count;}public int[] getNext(String S) {int l = S.length();// 获得next数组int[] next = new int[l];next[0] = 0; //没有公共前缀int j = 0;// AABAS// 01for (int i = 1; i < l; i++) {while (j > 0 && S.charAt(j) != S.charAt(i)) {j = next[j - 1]; //会退一步判断// :next[j - 1] 表示在 S[0...j-1] 这个子字符串中,最长的相同前缀和后缀的长度。如果 S[j] 和当前要比较的字符不匹配,这意味着 S[j] 不能作为前缀的一部分,因此需要找到一个更短的前缀,使得 S[0...next[j-1]] 和 S[i...] 能够匹配。}if (S.charAt(j) == S.charAt(i)) {j++;}next[i] = j; //验证到了这一步了。}return next;}
}

第二次出现的j=next[j-1]; 不是在 “j 往前走的时候已经经历过了” 的位置停止,而是在每次找到匹配或确定不匹配后,为下一次可能的匹配做准备。将 j 设置为 next[j-1] 允许我们在 T 的下一个字符处继续搜索。这是因为 S[0…next[j-1]] 已经是一个匹配的前缀,我们可以从这个前缀的末尾开始,尝试与 T 中的下一个字符匹配。

避免重复匹配:如果我们将 j 重置为 0,那么我们会在 T 中重复计算已经匹配的 S 的部分。使用 next[j-1] 确保我们不会重复计算,并且可以继续从 T 的下一个字符开始搜索。

优化搜索过程:通过这种方式,KMP 算法可以在找到一次匹配后,快速跳到可能的下一个匹配位置,而不必从头开始搜索,从而提高搜索效率。

#2、DFS回溯剪枝法
在这里插入图片描述
想到了树,不同的子节点,深度遍历下去有不同的路径结果。
分析题意:

X.X.X.X 每个X∈[0,255], 要求不同出现0M,M∈[0,9]
剩余X的个数1<=字符串的长度<=剩余X的个数3(因为X是1到3位数组成)

树有不同的子节点,子节点的子节点…
即树的不同层代表着字符串s的剩余长度,即当前走到了s的哪一位了(索引位置cur)。

  public void dfs(String s,int cur){if(tmp.size()==4&& cur==s.length()){res.add(tmp.get(0)+"."+tmp.get(1)+"."+tmp.get(2)+"."+tmp.get(3));}//jianzhi if(s.length()-cur>3*(4-tmp.size()))//每段大于3{return;}if(s.length()-cur<4-tmp.size())//小于1{return;}int num=0;//当前节点的操作,即X.X.X.X中的一个X   //X:从s的某个位置(索引cur)开始,i∈[cur,cur+2],且i<s.length()for(int i=cur;i<cur+3&&i<s.length();i++)//一个一个数字的判断{//0,1,2num=num*10+(s.charAt(i)-'0');//数字//百十个位if(num<0||num>255)//数字越界了就不要了,{break;}//tmp.add(s.substring(cur,i+1));//截取【0,255】之间的数字//判断写一个位置上可能的Xdfs(s,i+1);//继续判断tmp.remove(tmp.size()-1);//为啥?// 回溯允许算法“回到”上一个状态,重新考虑不同的数字组合。if(num==0){break;//只能0.不能02|09这些}}}
import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param s string字符串 * @return string字符串ArrayList*/ArrayList<String> res=new ArrayList<>();ArrayList<String> tmp=new ArrayList<>();public ArrayList<String> restoreIpAddresses (String s) {// write code here// 限制每一个[1,3]位置以及如果是3,那么数字小于255,否则,挪给别的,// >1则不能以0开头// 根据位数判断dfs(s,0);return res;}public void dfs(String s,int cur){if(tmp.size()==4&& cur==s.length()){res.add(tmp.get(0)+"."+tmp.get(1)+"."+tmp.get(2)+"."+tmp.get(3));}//jianzhi if(s.length()-cur>3*(4-tmp.size()))//每段大于3{return;}if(s.length()-cur<4-tmp.size())//小于1{return;}int num=0;for(int i=cur;i<cur+3&&i<s.length();i++)//一个一个数字的判断{//0,1,2num=num*10+(s.charAt(i)-'0');//数字if(num<0||num>255)//数字越界了就不要了,{break;}tmp.add(s.substring(cur,i+1));//截取【0,255】之间的数字dfs(s,i+1);//继续判断tmp.remove(tmp.size()-1);//为啥?// 回溯允许算法“回到”上一个状态,重新考虑不同的数字组合。if(num==0){break;//只能0.不能02|09这些}}}
}

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

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

相关文章

【目录】阅读须知!全博文、专栏大纲

首先要和大家说一下&#xff0c;博主的文章并不是想到哪里写到哪里&#xff0c;而是以整个大后端为主题&#xff0c;成体系的在写专栏&#xff0c;从和后端紧相关的计算机核心课程开始、到JAVA SE、JAVA EE、到数据库、MQ等各类中间件、再到业务场景、性能优化。当然也会涉及一…

【Go】常见的变量与常量

变量 常见的变量声明方式 一、声明单个变量的多种方式 1.声明一个变量初始化一个值 //声明变量 默认值是0&#xff0c;var a int//初始化一个值a 1fmt.Println(a) 2. 在初始化的时候省去数据类型&#xff0c;通过值自动匹配当前的变量的数据类型 var b 2fmt.Println(&quo…

html+css+js随机验证码

随机画入字符、线条 源代码在图片后面 点赞❤️关注&#x1f60d;收藏⭐️ 互粉必回 图示 源代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"…

【java web 01】3小时快速学习前端知识(收藏备用)

3小时快速学习前端知识【全栈专用】 一、教程简介1.1 Java 开发为何学Web技术1.2 课程设计1.3 课前准备 二、HTML2.1 Html简介2.1.1 HTML、CSS、JS分别有什么作用2.1.2 什么是HTML2.1.3 什么是标记语言 2.2 Hello&#xff0c;Html2.2.1 HTML基础结构2.2.2 专业词汇2.2.3 语法细…

C++入门(C语言过渡)

文章目录 前言一、C关键字二、命名空间三、C输入&输出四、缺省参数五、函数重载六、引用七、inline八、nullptr总结 前言 C是一种通用的、高级的、静态类型的编程语言&#xff0c;它在20世纪80年代由丹尼斯里奇创建的C语言基础上发展而来。以下是C发展的一些重要里程碑。 1…

[个人感悟] 消息队列应该考察哪些问题?

前言 消息队列. 不论是Java内部提供的LinkedBlockingQueue, 还是当下主流的中间件RabbitMQ, Kafka, RockMQ. 其本质上都是一个削峰填谷的工具. 我们都知道, 请求和流量都有可能瞬间很高, 或者很低. 所以, 很多时候, 我们需要请求存储起来, 或者使用异步的方式, 来匀速的处理过…

windows 11 + kali wsl二合一配置步骤与踩坑

windows 11 kali wsl二合一配置步骤与踩坑 在前几天的某市攻防演练中&#xff0c;在攻防前期&#xff0c;我的虚拟机经常无缘无故出现断网、卡顿等现象&#xff0c;但找不出原因。 为了不影响后续的这些天的攻防演练&#xff0c;我选择在一个晚上通宵 在我的windows 11系统上…

2024年电脑监控软件排行榜(真实测评推荐七款电脑监控软件)

在信息化快速发展的今天&#xff0c;企业对员工电脑活动的监控变得尤为重要。有效的电脑监控软件不仅可以提升员工的工作效率&#xff0c;还能防止信息泄露&#xff0c;保障企业的数据安全。本文将介绍几款知名的电脑监控软件&#xff0c;并对其特点进行详细分析&#xff0c;帮…

笔记本电脑投屏怎么操作?一看就会!

日常工作或办公都会用到笔记本电脑&#xff0c;但很多新手用户不知道笔记本电脑的投屏要怎么操作&#xff1f;接下来系统之家给大家介绍三种简单的操作方法&#xff0c;帮助大家轻松完成笔记本电脑投屏投屏操作&#xff0c;从而满足自己的办公或学习使用需求。 方法一 1. 直接W…

Django QuerySet对象,exclude()方法

模型参考上一章内容&#xff1a; Django QuerySet对象&#xff0c;filter()方法-CSDN博客 exclude()方法&#xff0c;用于排除符合条件的数据。 1&#xff0c;添加视图函数 Test/app11/views.py from django.shortcuts import render from .models import Postdef index(re…

Eclipse运行main函数报 launch error

右键run as java application&#xff0c;运行main函数的时候报launch error 解决方式&#xff1a;文件右键run configurations 旧的是Project JRE&#xff0c;改成下图这个样子

Windows7彻底卸载mysql

1.控制面板卸载mysql 2.删除C:\Program Files\MySQL 3.删除C:\用户\Administrator\App Data\Roaming\MySQL”(App Data默认隐藏&#xff0c;需要在文件夹和搜索选项中勾选显示文件夹),为了删除的更彻底&#xff0c;可以直接在计算机全盘搜索MySQL关键字&#xff0c;将所有找到…

软件测试下的AI之路(5)

😏作者简介:博主是一位测试管理者,同时也是一名对外企业兼职讲师。 📡主页地址:【Austin_zhai】 🙆目的与景愿:旨在于能帮助更多的测试行业人员提升软硬技能,分享行业相关最新信息。 💎声明:博主日常工作较为繁忙,文章会不定期更新,各类行业或职场问题欢迎大家…

Unity之Text组件换行\n没有实现+动态中英互换

前因:文本中的换行 \n没有换行而是打印出来了,解决方式 因为unity会默认把\n替换成\\n 面板中使用富文本这个选项啊 没有用 m_text.text = m_text.text.Replace("\\n", "\n"); ###动态中英文互译 using System.Collections; using System.Collections…

顺序表与链表

前言&#xff1a; 顺序表和链表是属于数据结构中比较基础的知识&#xff0c;我们需要对其进行掌握。在JAVA原生标准库中分别为ArrayList和LinkedList。下图是整个数据结构之间的结构框图 1.ArrayList 背后用来存储数据的是一个数组&#xff0c;所以用ArrayList来进行相关操作…

前端面试题23(css3)

关于CSS3的面试题&#xff0c;我们可以从多个维度来探讨&#xff0c;包括但不限于选择器、盒模型、布局技术、动画与过渡、响应式设计等。下面我会列举一些典型的CSS3面试问题&#xff0c;并尽可能提供详细的解答或示例代码。 1. CSS3中新增了哪些选择器&#xff1f; 答案: C…

JAVA之(static关键字、final关键字)

JAVA之&#xff08;static关键字、final关键字&#xff09; 一、 static关键字1、静态变量2、静态方法3、 静态代码块4、例子 二、final关键字1、final修饰类2、 final修饰方法3、修饰变量 一、 static关键字 1、静态变量 private static String str1“staticProperty”2、静…

SAP 无权限的解决

在进行SAP操作过程中&#xff0c;经常会出现无权限的情况&#xff0c;如客户说没有“ABAAL计划外折旧”权限 但是在查看SU01的时候&#xff0c;已经有角色分配了 解决&#xff1a;1、ABAA之后&#xff0c;SU53查看2、 2、PFCG查找到角色手动添加权限对象S_TCODDE,之后更新&…

YOLOv9报错:AttributeError: ‘list‘ object has no attribute ‘view‘

报错信息如下&#xff1a; red_distri, pred_scores torch.cat([xi.view(feats[0].shape[0], self.no, -1) for xi in feats], 2).split( AttributeError: ‘list’ object has no attribute ‘view’ 解决方法&#xff1a; 去yolov9/utils/loss_tal.py把167行代码更改&#…

Trinity:转录组从头组装

安装 #下载安装包 wget -c https://github.com/trinityrnaseq/trinityrnaseq/releases/download/Trinity-v2.15.1/trinityrnaseq-v2.15.1.FULL.tar.gztar -xzvf trinityrnaseq-v2.15.1.FULL.tar.gz cd trinityrnaseq-v2.15.1 make make plugins #安装依赖 mamba install -c bio…