实现 strStr()(Implement strStr())
题目描述:
实现 strStr() 函数。给定两个字符串 haystack 和 needle,在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1。
示例:
输入:haystack = "hello", needle = "ll"
输出:2
输入:haystack = "aaaaa", needle = "bba"
输出:-1
解题思路:
-
暴力匹配法:
- 遍历
haystack字符串,逐个字符与needle进行比较。 - 时间复杂度:O((n-m)*m),其中 n 是
haystack长度,m 是needle长度。
- 遍历
-
KMP 算法:
- 利用部分匹配表(Partial Match Table)优化匹配过程。
- 时间复杂度:O(n+m),空间复杂度:O(m)。
代码实现(暴力匹配法):
function strStr(haystack, needle) {
if (needle === "") return 0; // 空字符串返回 0
const n = haystack.length;
const m = needle.length;
for (let i = 0; i <= n - m; i++) {
let j = 0;
while (j < m && haystack[i + j] === needle[j]) {
j++;
}
if (j === m) return i; // 完全匹配
}
return -1; // 未找到
}
// 测试
console.log(strStr("hello", "ll")); // 输出 2
console.log(strStr("aaaaa", "bba")); // 输出 -1
代码实现(KMP 算法):
function strStr(haystack, needle) {
if (needle === "") return 0;
const n = haystack.length;
const m = needle.length;
// 构建部分匹配表
const lps = buildLPS(needle);
let i = 0, j = 0;
while (i < n) {
if (haystack[i] === needle[j]) {
i++;
j++;
if (j === m) return i - j; // 完全匹配
} else if (j > 0) {
j = lps[j - 1]; // 利用部分匹配表回退
} else {
i++;
}
}
return -1;
}
function buildLPS(needle) {
const lps = new Array(needle.length).fill(0);
let len = 0, i = 1;
while (i < needle.length) {
if (needle[i] === needle[len]) {
len++;
lps[i] = len;
i++;
} else if (len > 0) {
len = lps[len - 1];
} else {
lps[i] = 0;
i++;
}
}
return lps;
}
// 测试
console.log(strStr("aabaaabaaac", "aabaaac")); // 输出 4
console.log(strStr("mississippi", "issip")); // 输出 4
复杂度分析:
- 暴力匹配法:
- 时间复杂度:O((n-m)*m)
- 空间复杂度:O(1)
- KMP 算法:
- 时间复杂度:O(n+m)
- 空间复杂度:O(m)
总结:
- 暴力匹配法简单直观,适合处理小规模字符串匹配
- KMP 算法通过预处理模式串,优化了匹配效率,适合处理大规模字符串匹配
- 在实际面试中,可以先实现暴力解法,再优化为KMP算法