返回
从复杂到简单、易懂清晰的LeetCode-28解析
前端
2023-09-25 08:37:32
从复杂到简单,LeetCode-28详解
算法概述
LeetCode-28: 实现strStr()函数,该函数接受两个字符串参数haystack和needle,并返回needle在haystack中的第一个出现位置。如果needle不在haystack中,则返回-1。
暴力匹配法
暴力匹配法是最简单、最直观的算法,但也是最慢的算法。其思想是,将needle逐个字符与haystack进行比较,如果发现匹配,则继续比较后续字符,直到needle所有字符都匹配成功或haystack结束为止。如果在haystack中没有找到与needle匹配的子串,则返回-1。
function strStr(haystack, needle) {
if (needle === '') {
return 0;
}
for (let i = 0; i <= haystack.length - needle.length; i++) {
let found = true;
for (let j = 0; j < needle.length; j++) {
if (haystack[i + j] !== needle[j]) {
found = false;
break;
}
}
if (found) {
return i;
}
}
return -1;
}
Knuth-Morris-Pratt(KMP)算法
KMP算法是一种高效的字符串匹配算法,它通过预处理needle字符串,构造一个next数组,来减少字符串比较次数。next数组的每个元素next[i]表示needle子串的前i个字符的最长公共前缀和后缀的长度。
function strStr(haystack, needle) {
if (needle === '') {
return 0;
}
const next = getNextArray(needle);
let i = 0;
let j = 0;
while (i < haystack.length) {
if (haystack[i] === needle[j]) {
i++;
j++;
if (j === needle.length) {
return i - j;
}
} else if (j > 0) {
j = next[j - 1];
} else {
i++;
}
}
return -1;
}
function getNextArray(needle) {
const next = new Array(needle.length).fill(0);
next[0] = -1;
let i = 0;
let j = -1;
while (i < needle.length - 1) {
if (j === -1 || needle[i] === needle[j]) {
i++;
j++;
next[i] = j;
} else {
j = next[j];
}
}
return next;
}
实践建议
- 在编写算法时,应该先考虑最简单、最直观的算法。如果该算法无法满足性能要求,再考虑使用更复杂的算法。
- 在学习算法时,应该先理解算法的思想和原理,再考虑算法的具体实现。
- 在练习算法时,应该选择不同难度的算法,并逐步提高难度。
扩展阅读