LeetCode-28. Implement strStr()https://leetcode.com/problems/implement-strstr/
Implement?strStr().
Given two strings?needle ?and?haystack , return the index of the first occurrence of?needle ?in?haystack , or?-1 ?if?needle ?is not part of?haystack .
Clarification:
What should we return when?needle ?is an empty string? This is a great question to ask during an interview.
For the purpose of this problem, we will return 0 when?needle ?is an empty string. This is consistent to C's?strstr()?and Java's?indexOf().
Example 1:
Input: haystack = "hello", needle = "ll"
Output: 2
Example 2:
Input: haystack = "aaaaa", needle = "bba"
Output: -1
Constraints:
1 <= haystack.length, needle.length <= 10^4 haystack ?and?needle ?consist of only lowercase English characters.
【C++】
class Solution {
public:
int strStr(string haystack, string needle) {
int k = -1, n = haystack.length(), p = needle.length();
if (p == 0) {return 0;}
vector<int> next(p, -1); // -1表示不存在相同的最大前缀和后缀
calNext(needle, next); // 计算next数组
for (int i = 0; i < n; ++i) {
// 有部分匹配,往前回溯
while (k > -1 && needle[k+1] != haystack[i]) {k = next[k];}
if (needle[k+1] == haystack[i]) {++k;}
// 说明k移动到needle的最末端,返回相应的位置
if (k == p-1) {return i-p+1;}
}
return -1;
}
// 辅函数- 计算next数组
void calNext(const string &needle, vector<int> &next) {
for (int j = 1, p = -1; j < needle.length(); ++j) {
// 如果下一位不同,往前回溯
while (p > -1 && needle[p+1] != needle[j]) {p = next[p];}
// 如果下一位相同,更新相同的最大前缀和最大后缀长
if (needle[p+1] == needle[j]) {++p;}
next[j] = p;
}
}
};
【Java】
class Solution {
public int strStr(String haystack, String needle) {
int k = -1, n = haystack.length(), p = needle.length();
if (p == 0) {return 0;}
int[] next = new int[p];
Arrays.fill(next, -1); // -1表示不存在相同的最大前缀和后缀
calNext(needle, next); // 计算next数组
for (int i = 0; i < n; ++i) {
// 有部分匹配,往前回溯
while (k > -1 && needle.charAt(k+1) != haystack.charAt(i)) {k = next[k];}
if (needle.charAt(k+1) == haystack.charAt(i)) {++k;}
// 说明k移动到needle的最末端,返回相应的位置
if (k == p-1) {return i-p+1;}
}
return -1;
}
// 辅函数- 计算next数组
void calNext(String needle, int[] next) {
for (int j = 1, p = -1; j < needle.length(); ++j) {
// 如果下一位不同,往前回溯
while (p > -1 && needle.charAt(p+1) != needle.charAt(j)) {p = next[p];}
// 如果下一位相同,更新相同的最大前缀和最大后缀长
if (needle.charAt(p+1) == needle.charAt(j)) {++p;}
next[j] = p;
}
}
}
参考文献
【1】【算法图文动画详解系列】KMP 字串匹配搜索算法_东海陈光剑的博客-CSDN博客
|