题目
实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回-1。
示例 1:
输入: haystack = "hello", needle = "ll"
输出: 2
示例 2:
输入: haystack = "aaaaa", needle = "bba"
输出: -1
来源:力扣(LeetCode)
解答
其他方法略,仅针对kmp算法。
先上代码:
func strStr(haystack string, needle string) int {
if len(needle) == 0 {
return 0
}
next := getNext(needle)
i, j := 0, 0
for i < len(haystack) && j < len(needle) {
if j == -1 || haystack[i] == needle[j] {
i++
j++
} else {
j = next[j]
}
}
if j >= len(needle) {
return i - len(needle)
} else {
return -1
}
}
func getNext(needle string) []int{
var next []int=make([]int,len(needle))
next[0] = -1
k:=-1
j:=0
for j<len(needle)-1{
if k==-1||needle[k]==needle[j]{
k++
j++
next[j]=k
}else{
k=next[k]
}
}
return next
}
主要为思路两个部分:
- 计算子字符串的
next
表//或称prefix
表 - 根据计算的
next
表,进行匹配
1. next表
2. 主函数匹配
思路如下:
分配i
和j
指向T(代码中的haystack)和P(代码中的needle)字符串。
依次比较T[i]
和P[j]
,
-
相等
i
和j
分别自增1,比较下一个字符 -
不相等
回退,根据next表进行回退。
取next[j]
中的值,重新赋值给j
,让j
回退到next表中指定的位置。
以上比较有一个条件限制,就是i
和j
的值应分别小于对应字符串的长度
当循环比较结束后,进行判定:
-
j >= len(P)
此时表示,退出循环前,是将子字符串P
中的每一个字符都对应上了T
字符串。
因此,此时找到了对应的匹配位置,返回的位置就是i
减去P的长度(因为匹配成功,经历了len(P)
的i和j自增1) -
不满足1
退出循环前,并没有全匹配P字符串,因此返回-1