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

27-算法打卡-字符串-找出字符串中第一个匹配项的下标-leetcode(28)-第二十七天

1 题目地址

28. 找出字符串中第一个匹配项的下标 - 力扣(LeetCode)28. 找出字符串中第一个匹配项的下标 - 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回  -1 。 示例 1:输入:haystack = "sadbutsad", needle = "sad"输出:0解释:"sad" 在下标 0 和 6 处匹配。第一个匹配项的下标是 0 ,所以返回 0 。示例 2:输入:haystack = "leetcode", needle = "leeto"输出:-1解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。 提示: * 1 <= haystack.length, needle.length <= 104 * haystack 和 needle 仅由小写英文字符组成https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/description/


2 题目说明

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回  -1 

示例 1:

输入:haystack = "sadbutsad", needle = "sad"
输出:0
解释:"sad" 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0 。

示例 2:

输入:haystack = "leetcode", needle = "leeto"
输出:-1
解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。

提示:

  • 1 <= haystack.length, needle.length <= 104
  • haystack 和 needle 仅由小写英文字符组成

3 解题思路

方式一:暴力方式:两层循环
1、假设字符串haystack长度是m,needle长度是n
2、haystack匹配needle最多需要循环次数是m-n+1
3、第一层循环是最多需要遍历的次数m-n+1,即haystack的起始的索引下标位置
4、第二层循环每次都是从0开始最大到needle长度n,判断两层的指向的字符是否相等,
        不相等:直接跳出第二层循环
        相等:第二层是否遍历到needle的末尾
                是:直接返回第一层索引下标(结果)
                否:上下两层同时向后移动

方式二:KMP

查看 28-算法打卡-字符串-KMP算法理论-第二十八天-CSDN博客、29-算法打卡-字符串-KMP算法理论2-第二十九天-CSDN博客

核心思想是记录已经遍历过的模式串的特征,当匹配失败的时候只需要模式串退回,文本串继续向右移动,减少时间复杂度O(m+n)。

 获取前缀表(next数组):
1、初始化:初始化指针i j, j指向前缀的末尾也是子串的最长公共前后缀、i指向后缀的
末尾也是待更新next数组的位置; j=0,next[0]=0
2、前后缀相同: j向右移动,next[i]=j
3、前后缀不相同:j回退到next[j-1]位置 ,不相等一直回退,即是while,而不是if

4、更新next数组,next[i]=j

 获取匹配下标:

1、获取next数组

2、定义指针i j,i指向haystack 开始位置(0), j指向needle开始位置(0)

3、文本串和模式串指向的位置相同时:则两者都继续向右移动
4、文本串和模式串指向的位置不相同时:模式串退回到next[j-1]的位置

4 代码编写


4.1 暴力方式

class Solution {public int strStr(String haystack, String needle) {char[] haystackArray = haystack.toCharArray();char[] needleArray = needle.toCharArray();int haystackLength = haystackArray.length;int needleLength = needleArray.length;// 需要匹配的次数int need = haystackLength - needleLength + 1;for (int i=0; i<need; i++) {int left = i;int needleInit = 0;while (needleInit<needleLength) {// 字符相等if (haystackArray[left] == needleArray[needleInit]) {// 最后一个元素也匹配直接返回if (needleInit == needleLength-1) {return i;}// 否则都向后移动left++;needleInit++;} else {// 不相等,直接跳出本层循环break;}}}return -1;}}

简化上面代码方式:

class Solution {public int strStr(String haystack, String needle) {char[] haystackArray = haystack.toCharArray();char[] needleArray = needle.toCharArray();int haystackLength = haystackArray.length;int needleLength = needleArray.length;// 需要匹配的次数int need = haystackLength - needleLength + 1;for (int i=0; i<need; i++) {int left = i;int needleInit = 0;// 匹配则向后移动while (needleInit<needleLength && haystackArray[left] == needleArray[needleInit]) {left++;needleInit++;}// 最后一个元素也匹配直接返回if (needleInit == needleLength) {return i;}}return -1;}}


4.2 KMP

class Solution {public int strStr(String haystack, String needle) {int m = haystack.length();int n = needle.length();int[] next = new int[n];getNext(needle, next);int j = 0;for (int i=0; i<m; i++) {while (j>0 && haystack.charAt(i) != needle.charAt(j)) {j = next[j-1];}if (haystack.charAt(i) == needle.charAt(j)) {j++;}if (j==n) {return (i-j+1);}}return -1;}// 获取前缀表public void getNext(String needle, int[] next) {// 初始化,j后缀的末尾,子串的最长公共前后缀int j = 0;next[0] = 0;// i前缀的末尾,数组next更新索引位置for (int i=1; i<needle.length(); i++) {while (j>0 && needle.charAt(i)!= needle.charAt(j)) {// 向左回退j = next[j-1];}// 匹配成功向右移动if (needle.charAt(i)== needle.charAt(j)) {j++;}// 更新数组next[i] = j;}}}


http://www.mrgr.cn/news/100348.html

相关文章:

  • 当高级辅助驾驶遇上“安全驾校”:NVIDIA如何用技术给无人驾驶赋能?
  • 2:QT联合HALCON编程—图像显示放大缩小
  • classfinal 修改过源码,支持jdk17 + spring boot 3.2.8
  • 逻辑运算符
  • Leetcode刷题记录19——无重复字符的最长子串
  • 揭开人工智能的神秘面纱:从概念到人工神经网络
  • (四) 实战Trae 编译调试C++项目(以minidocx为例)
  • gem5-gpu教程05 内存建模
  • 《USB技术应用与开发》第四讲:实现USB鼠标
  • 树状数组底层逻辑探讨 / 模版代码-P3374-P3368
  • C++指针(三)
  • matplotlib画图工具使用(1) 画折线统计图python代码
  • 海思ISP调试记录
  • Java实现HTML转PDF(deepSeekAi->html->pdf)
  • ubantu中下载编译安装qt5.15.3
  • 使用java代码注册onloyoffice账号 || 注册onloyoffice账号
  • WPF之项目创建
  • Flutter 弹窗队列管理:支持优先级的线程安全通用弹窗队列系统
  • 前端面试之吊打面试官 HTML篇
  • k8s 1.26版部署