开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第9天,点击查看活动详情
1.找出字符串中第一个匹配下标
题目描述
解题思路
1.理解前缀表及后缀表,前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串;后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串
2.构建next数组,找出needle字符串的最长相等前后缀,next数组统计每个字符的公共前后缀。
3.循环haystack字符串,使用next数组来匹配,找出第一个匹配位置
var strStr = function(haystack, needle) {
if(needle.length === 0) return 0
const next = new Array(needle.length);
getNext(next,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
};
var getNext = function(next,s){
let j = -1
next[0] = -1;
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[i] = j;
}
}
2.重复的子字符串
题目描述
解题思路
本题思路与上面一题一致,构建next数组,统计每个字符的最长相等公共前后缀。循环时判断数组的长度正好可以被 (数组长度-最长相等前后缀的长度) 整除 ,说明该字符串有重复的子字符串即可
var repeatedSubstringPattern = function(s) {
if(s.length===0) return false
const next = new Array(s.length)
getNext(next,s)
const len = s.length;
if (next[len - 1] != -1 && len % (len - (next[len - 1] + 1)) == 0) {
return true;
}
return false;
};
var getNext = function(next,s){
let j = -1
next[0] = -1;
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[i] = j;
}
}