索引:[LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql)
Github: https://github.com/illuz/leetcode
题目:https://oj.leetcode.com/problems/implement-strstr/
代码(github):https://github.com/illuz/leetcode
在一个字符串里找另一个字符串在其中的位置。
这题归在 Easy 类是因为它 O(n*n) 的暴力能过。
如果数据强点就得 Midium 以上了。
((hash << 5) + hash)
很快,不过 int 范围只能 hash 6 个字母而且 rolling 的时候还是要 /33
,还是用 29 算了),超 int 范围的话用 Python 就不用考虑这个问题了。其他还有 Boyer–Moore,Rabin–Karp 算法,具体自己去搜。
C++: 暴力
class Solution {
public:
int strStr(char *haystack, char *needle) {
int hlen = strlen(haystack);
int nlen = strlen(needle);
if (hlen < nlen)
return -1;
for (int i = 0; i <= hlen - nlen; i++) {
if (!strncmp(haystack + i, needle, nlen))
return i;
}
return -1;
}
};
C++: KMP
class Solution {
private:
int next[1000100];
public:
int strStr(char *haystack, char *needle) {
int hlen = strlen(haystack);
int nlen = strlen(needle);
int i, j;
if (hlen < nlen)
return -1;
if (nlen == 0)
return 0;
// KMP
// get next matching array
// int *next = new int(nlen + 1);
// Because the string will be 1 million, so we cannot use `int *next = new int(nlen + 1)`, it will exceed the memory in function
i = 0;
j = -1;
next[0] = -1;
while (i < nlen) {
if (j == -1 || needle[i] == needle[j]) {
i++;
j++;
next[i] = j;
} else
j = next[j];
}
// matching
i = 0;
j = 0;
while (i < hlen) {
if (j == -1 || haystack[i] == needle[j]) {
i++;
j++;
} else
j = next[j];
if (j == nlen)
return i - nlen;
}
return -1;
}
};
Python:
class Solution:
# @param haystack, a string
# @param needle, a string
# @return an integer
def strStr(self, haystack, needle):
hlen, nlen = len(haystack), len(needle)
if nlen == 0:
return 0
if nlen > hlen or hlen == 0:
return -1
rolling = lambda x, y: x * 29 + y
get_hash = lambda ch: ord(ch) - ord('a')
nhash = reduce(rolling, map(get_hash, needle))
hhash = reduce(rolling, map(get_hash, haystack[:nlen]))
if nhash == hhash:
return 0
high_base = 29 ** (nlen - 1)
for i in range(nlen, hlen):
hhash -= get_hash(haystack[i - nlen]) * high_base # remove first in hash code
hhash = rolling(hhash, get_hash(haystack[i])) # add new
if nhash == hhash:
return i - nlen + 1
return -1