看leetCode没看懂,然后google+chatGPT基本把我讲明白
1. 思路
- 求取模板字符串的LPS(Longest Prefix Suffix)
// 构建部分匹配表
function buildLPS(pattern) {
const lps = new Array(pattern.length).fill(0);
let length = 0, i = 1;// length 为已知的最长“签证 == 后缀”长度
while(i < pattern.length) {
if (pattern[i] === pattern[length]) {
length++;
lps[i] = length;
i++;
} else {
if (length != 0) {
// !!!! 这是关键关键!!!!
length = lps[length - 1];//反复退回前面最长相等前后缀的方式
} else {
lps[i] = 0;
i++;
}
}
}
}
🔍 以 "ABCDABD" 为例,打印输出:
console.log(buildLPS("ABCDABD"));
// 输出: [0, 0, 0, 0, 1, 2, 0]
你可以逐个对应:
A
: 无前后缀,共同长度 0AB
: 前[A],后[B] → 0ABC
: 前[A, AB],后[BC, C] → 0ABCD
: … → 0ABCDA
: 前[A, AB, ABC, ABCD],后[BCDA, CDA, DA, A] → "A" → 1ABCDAB
: … → "AB" → 2ABCDABD
: … → 无 → 0
2. 按题目求解
var strStr = function(haystack, needle) {
if (needle.length === 0) return 0;
let lps = buildLPS(needle);
let i = 0, 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 = lps[j - 1];
} else {
i++;
}
}
}
return -1;
};
3. 算法复杂度
O(m+n)