leetcode28. 找出字符串中第一个匹配项的下标
一、题目描述
给你两个字符串 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 仅由小写英文字符组成
二、题目解析
1、暴力解法,双指针法,枚举原串 ss 中的每个字符作为「发起点」,每次从原串的「发起点」和匹配串的「首位」开始尝试匹配
class Solution {public int strStr(String haystack, String needle) {if(haystack == null || needle == null || haystack.length() < needle.length()){return -1;}int count = 0,i = 0,j = 0,res = -1;while(i < haystack.length() && j < needle.length()){while(count == 0 && i < haystack.length() && haystack.charAt(i) != needle.charAt(j)){i++;}//预防while循环里的i因不断递增越界if(i >= haystack.length()){return -1;}//haystack包含部分needle但未完全包含,需从当前res的下一个位置开始匹配,count,res和j重置if(count > 0 && count < needle.length() && haystack.charAt(i) != needle.charAt(j)){count = 0;j = 0;i = res + 1;res = -1;continue;}if(haystack.charAt(i) == needle.charAt(j)){//第一个匹配的元素需记录当前位置作为开始位置if(count == 0){res = i;}count++;i++;j++;//若count积累到了needle的长度,则此次res为所求起始位置if(count == needle.length()){return res;}}}return -1;}
}
2、在1的基础上代码可优化
可用for循环遍历haystack的每一个可能起始位置,内部用临时变量a记录,在匹配过程中不需要回溯
class Solution {public int strStr(String ss, String pp) {int n = ss.length(), m = pp.length();char[] s = ss.toCharArray(), p = pp.toCharArray();// 枚举原串的「发起点」for (int i = 0; i <= n - m; i++) {// 从原串的「发起点」和匹配串的「首位」开始,尝试匹配int a = i, b = 0;while (b < m && s[a] == p[b]) {a++;b++;}// 如果能够完全匹配,返回原串的「发起点」下标if (b == m) return i;}return -1;}
}
3、kmp算法
https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/solutions/2600821/kan-bu-dong-ni-da-wo-kmp-suan-fa-chao-qi-z1y0/