文章目录
- 28.找出字符串中第一个字符的匹配项
- 思路
- 复杂度
- 暴力求解
- KMP算法求解
- 总结
28.找出字符串中第一个字符的匹配项
实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
示例 1: 输入: haystack = "hello", needle = "ll" 输出: 2
示例 2: 输入: haystack = "aaaaa", needle = "bba" 输出: -1
思路
- 滑动窗口+双指针
- 步骤1:找到第一个字符串匹配的位置
- 步骤2:从字符串匹配的首字符开始,双指针移动
- 步骤3:模式串的指针指向模式串的长度,则完成匹配
- 步骤4:第一个字符匹配后,遇见冲突,i指针回退到i-j-1位置
复杂度
- 时间 O(n*m)
- 空间 O(1)
暴力求解
class Solution {
public int strStr(String haystack, String needle) {
//模式串为空,返回0
int n = haystack.length(), m = needle.length();
if (m == 0) {
return 0 ;
}
if(n < m){
return -1;
}
int i = 0 ,j = 0;
while (i < (n - m + 1)) {
//判断两个字符串的首字符是否相同
while(i<n && haystack.charAt(i) != needle.charAt(j)){
i++;
}
if(i == n){
return -1 ;
}
//文本串和模式串首字符相同
while (i < n && j < m && haystack.charAt(i) == needle.charAt(j)) {
i++;j++;
}
//j 等于模式串长度时,说明匹配结束,返回开始字符小标
if(j == m){
return i- j ;
}else{
//出现未匹配字符,i还原到匹配前的位置
i -= j -1;
j = 0 ;
}
}
return -1;
}
}
KMP算法求解
-
思路
-
求模式串的前缀表
-
找到文本串中匹配到的第一个字符的问题(字符不相等需要一直寻找,用到while),回退到前一位对应的下标的位置
-
字符串相同则指针同时向后移动
-
模式串指针等于长度时,说明完全匹配,返回
i=m+1
-
-
时间复杂度O(m+n)
-
空间复杂度O(m)
class Solution {
public int strStr(String haystack, String needle) {
//模式串为空,返回0
int n = haystack.length(), m = needle.length();
if (m == 0) {
return 0 ;
}
if(n < m){
return -1;
}
int[] next = new int[m];
getNext(next,needle);
//字符串前缀的最后一个字符的位置
int j = 0;
for (int i = 0; i < n; i++) {
while (j > 0 && haystack.charAt(i) != needle.charAt(j)) {
j = next[j-1];
}
if (haystack.charAt(i) == needle.charAt(j)) {
j++;
}
if(j == m){
return i-m +1;
}
}
return -1;
}
public void getNext(int[] next, String s) {
int j = 0 ;
next[0] = 0 ;
for (int i = 1; i < s.length(); i++) {
//1、字符不等,回退j
while(j>0 && s.charAt(i) != s.charAt(j)){
j = next[j-1];
}
if(s.charAt(i) == s.charAt(j)){
j++;
}
next[i] =j;
}
}
}
解答成功:
执行耗时:0 ms,击败了100.00% 的Java用户
内存消耗:39.3 MB,击败了69.87% 的Java用户
总结
- 参考资料:/0028.%E5%AE%9E%E7%8E%