Easy | LeetCode 28. 实现 strStr() | 设计实现
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() 定义相符。
解题思路
方法一: KMP 算法
方法二: Rabin Karp 算法
class Solution {
// 字符转整数
public int charToInt(int idx, String s) {
return (int)s.charAt(idx) - (int)'a';
}
public int strStr(String haystack, String needle) {
int L = needle.length(), n = haystack.length();
if (L > n) return -1;
// base value for the rolling hash function
int a = 26;
// modulus value for the rolling hash function to avoid overflow
long modulus = (long)Math.pow(2, 31);
// compute the hash of strings haystack[:L], needle[:L]
long h = 0, ref_h = 0;
for (int i = 0; i < L; ++i) {
h = (h * a + charToInt(i, haystack)) % modulus;
ref_h = (ref_h * a + charToInt(i, needle)) % modulus;
}
if (h == ref_h) return 0;
// const value to be used often : a**L % modulus
long aL = 1;
for (int i = 1; i <= L; ++i) {
aL = (aL * a) % modulus;
}
for (int start = 1; start < n - L + 1; ++start) {
// compute rolling hash in O(1) time
h = (h * a - charToInt(start - 1, haystack) * aL
+ charToInt(start + L - 1, haystack)) % modulus;
if (h == ref_h) return start;
}
return -1;
}
}