学习时间:
- 晚上 八点—晚上十点
28. 实现 strStr
思路:
本题是KMP 经典题目。KMP的经典思想就是:当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配。
代码实现:
//前缀表统一减一
var strStr = function (haystack, needle) {
if (needle.length === 0) {
return 0;
}
const getNext = (needle) => {
let next = [];
let j = -1;
next.push(j);
for (let i = 1; i < needle.length; ++i) {
while (j >= 0 && needle[i] !== needle[j + 1]) {
//向前回退
j = next[j]
}
if (needle[i] === needle[j + 1]) {
j++
}
next.push(j)
}
return next
}
let next = getNext(needle)
let j = -1;
for (let i = 0; i < haystack.length; ++i) {
while (j >= 0 && haystack[i] !== needle[j + 1]) {
j = next[j]
}
if (haystack[i] === needle[j + 1]) {
j++
}
if (j === needle.length - 1) {
return (i - needle.length + 1)
}
}
return -1
};
// console.log(strStr("sadbutsad", "sad"))
//前缀表不统一减一
var strStrNew = function (haystack, needle) {
if (needle.length === 0) {
return 0;
}
const getNext = (needle) => {
let next = [];
let j = 0;
next.push(j);
for (let i = 1; i < needle.length; ++i) {
while (j > 0 && needle[i] !== needle[j]) {
//向前回退
j = next[j - 1]
}
if (needle[i] === needle[j]) {
j++
}
next.push(j)
}
return next
}
let next = getNext(needle)
let j = 0;
for (let i = 0; i < haystack.length; ++i) {
while (j > 0 && haystack[i] !== needle[j]) {
j = next[j - 1]
}
if (haystack[i] === needle[j]) {
j++
}
if (j === needle.length) {
return (i - needle.length + 1)
}
}
return -1
};
459.重复的子字符串
思路:只需要判断,以第一个字母为开始的子串就可以,所以一个for循环获取子串的终止位置就行了。 而且遍历的时候 都不用遍历结束,只需要遍历到中间位置,因为子串结束位置大于中间位置的话,一定不能重复组成字符串。
代码实现:
//前缀表统一减一
var repeatedSubstringPattern = function (s) {
if (s.length === 0) {
return false
}
const getNext = (s) => {
let next = []
let j = -1;
next.push(j)
for (let i = 1; i < s.length; ++i) {
while (j >= 0 && s[i] !== s[j + 1]) {
j = next[j];
}
if (s[i] === s[j + 1]) {
j++
}
next.push(j)
}
return next
}
let next = getNext(s)
if (next[next.length - 1] !== -1 && s.length % (s.length - (next[next.length - 1] + 1)) === 0) {
return true
}
return false
};
//前缀表统一不减一
var repeatedSubstringPattern = function (s) {
if (s.length === 0) {
return false
}
const getNext = (s) => {
let next = []
let j = 0;
next.push(j)
for (let i = 1; i < s.length; ++i) {
while (j > 0 && s[i] !== s[j]) {
j = next[j - 1];
}
if (s[i] === s[j]) {
j++
}
next.push(j)
}
return next
}
let next = getNext(s)
if (next[next.length - 1] !== 0 && s.length % (s.length - (next[next.length - 1])) === 0) {
return true
}
return false
};
总结:
初次接触kmp算法 感觉十分困难 next数组那里不太好理解 二刷时会重点关注,并着重复习