Implement strStr().
Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
Example
Ignored Cases
==Solution 1: iteration ==
Time Complexity: O((n-m)m) where n is haystack’s length and m is needle’s length. Space Complexity: O(1)
class Solution {
public int strStr(String haystack, String needle) {
if(haystack == null || haystack.length() < needle.length())
return -1;
if(needle == null || needle.isEmpty())
return 0;
int hLen = haystack.length();
int nLen = needle.length();
for(int i = 0; i<= hLen-nLen; i++) {
int j = 0;
for(; j < nLen; j++) {
if(haystack.charAt(i+j) != needle.charAt(j))
break;
}
if(j == nLen)
return i;
}
return -1;
}
}
Solution 2: KMP
consideration
- we use a next array to store the longest length of the prefix common to the postfix right before the current index. next[0] = -1 since there is no substring before index 0.
- For current index j, if p[j] != p [k+1], we let k = next[k]. Afterwards, we check if p[j] == p[k+1], we increase k by 1. Finally, set p[j] = k.
- For two string checks, we use i to iterate haystack and j to iterate needle.
- if(haystack[i] == needle[j]), we increase i and j both by 1.
- if(j == 0) which means we have reached the beginning of needle and haystack[i] != needle[j], then we increase i by 1.
- if(j > 0) and haystack[i] != needle[j], we let j be next[j-1]+1.
- if(j == needle.length), then the substring has been found, we return i-j.
class Solution {
public int strStr(String haystack, String needle) {
if(haystack == null || haystack.length() < needle.length())
return -1;
if(needle == null || needle.isEmpty())
return 0;
int hLen = haystack.length();
int nLen = needle.length();
int[] next = next(needle);
for(int i = 0, j=0; i< hLen; ) {
if(haystack.charAt(i) == needle.charAt(j)) {
i++;
j++;
} else if(j == 0 && haystack.charAt(i) != needle.charAt(j)){
i++;
} else if(j > 0 && haystack.charAt(i) != needle.charAt(j)) {
j = next[j-1]+1;
}
if(j == nLen)
return i-j;
}
return -1;
}
private int[] next(String p) {
int[] next = new int[p.length()];
next[0] = -1;
int k = -1;
int j = 1;
while(j < p.length()) {
while(k > -1 && p.charAt(j) != p.charAt(k+1)) {
k = next[k];
}
if(p.charAt(j) == p.charAt(k+1))
k = k+1;
next[j++] = k;
}
return next;
}
}
Reference