28. 实现 strStr()
实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
示例 1:
输入: haystack = "hello", needle = "ll" 输出: 2
示例 2:
输入: haystack = "aaaaa", needle = "bba" 输出: -1
说明:
当 needle
是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle
是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。
class Solution {
public int strStr(String haystack, String needle) {
/*1、沿字符串逐步移动窗口(窗口长度为needle的长度),
将窗口内的子串与needle进行比较。*/
/*时间复杂度:O((N - L)L),其中 N 为 haystack 字符串的长度,L 为 needle 字符串的长度。
内循环中比较字符串的复杂度为 L,总共需要比较 (N - L) 次。
空间复杂度:O(1)。*/
int win_len = needle.length();//窗口长度
int len = haystack.length();//字符串总长
//substring参数
//beginIndex -- 起始索引(包括), 索引从 0 开始;
//endIndex -- 结束索引(不包括)。
for(int start = 0; start < len - win_len + 1; start++){
if( haystack.substring(start,start+win_len).equals(needle)){
return start;
}
}
return -1;
/*2、优化1的方法,当子串的第一个字符与needle的第一个字符相同时需要进行比较。
单个字符进行比较,当字符不相等时立刻终止。
比较到最后一位时发现不匹配时开始回溯。
找到了完整匹配的子串,直接返回子串的开始位置。*/
/*时间复杂度:最坏时间复杂度为 O((N - L)L),最优时间复杂度为 O(N)。
空间复杂度:O(1)。*/
int win_len = needle.length();//窗口长度
int len = haystack.length();//字符串总长
if(win_len == 0){
return 0;
}
//设置主字符串移动指针,进行遍历
int point_h = 0;
while(point_h < len - win_len + 1){
//查看haystack中第一个与needle第一个字符相等的下标
while(point_h < len - win_len + 1 && (haystack.charAt(point_h) != needle.charAt(0))){
point_h = point_h + 1;
}
//查询到相等的字符,从该位置开始判定其余每位是否相等,并记录相同字符串的长度
int point_n = 0, cur_len = 0;
while(point_h < len && point_n < win_len && (haystack.charAt(point_h) == needle.charAt(point_n))){
point_h = point_h + 1;
point_n = point_n + 1;
cur_len = cur_len + 1;
}
//如果相等的字符串的长度与窗口也就是needle长度相同,返回point_h - win_len,即原字符串第一个字符相等的下标位
if(cur_len == win_len){
return point_h - win_len;
}
//否则,位置回到原字符串第一个字符串相等位置的下一位继续进行一次查询对比
point_h = point_h - cur_len + 1;
}
//未找到匹配字符
return -1;
}
}