28. 实现 strStr()简单暴力KMP
Posted pre_eminent
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了28. 实现 strStr()简单暴力KMP相关的知识,希望对你有一定的参考价值。
实现 strStr() 函数。
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
说明:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。
示例 1:
输入:haystack = "hello", needle = "ll"
输出:2
示例 2:
输入:haystack = "aaaaa", needle = "bba"
输出:-1
示例 3:
输入:haystack = "", needle = ""
输出:0
提示:
1 <= haystack.length, needle.length <= 10^4
haystack 和 needle 仅由小写英文字符组成
解法1:暴力
/**
* @param string haystack
* @param string needle
* @return number
*/
var strStr = function(s, p)
// 1.健壮性
if (p.length === 0 || s === p)
return 0;
let pLen = p.length;
// 对s字符串,从0开始,遍历至sLen - pLen位置处
// 注意等号
for(let i = 0; i <= s.length - pLen; i++)
let flag = true;
// 对p字符串:从0开始,遍历pLen长度
for (let j = 0; j < pLen; j++)
if (s.charAt(i + j) !== p.charAt(j))
flag = false;
break;
// 完全匹配上了
if (flag)
return i;
return -1;
;
/**
* @param string haystack
* @param string needle
* @return number
*/
var strStr = function(s, p)
// 1.健壮性
if (p.length === 0 || s === p)
return 0;
let pLen = p.length;
// 对s字符串,从0开始,遍历至sLen - pLen位置处
// 注意等号
for(let startIndex = 0; startIndex <= s.length - pLen; startIndex++)
// 对s字符串:从 startIndex 开始,遍历pLen长度
for(let i = startIndex; i < startIndex + pLen; i++)
let count = 0;
// 对p字符串:从0开始,遍历pLen长度
for (let j = 0; j < pLen; j++)
if (s.charAt(i) === p.charAt(j))
i++;
// j已经在for里++
count++;
else
// 直接break;
break;
// 完全匹配上了,回退i的位置至起始位置
if (count === pLen)
return i - pLen;
return -1;
;
解法2:KMP算法(next数组)
KMP算法视频(理论篇):https://bilibili.com/video/BV1PD4y1o7nd/
/**
* @param string haystack
* @param string needle
* @return number
*/
var strStr = function(s, p)
// 1.健壮性
if (p.length === 0)
return 0;
// 2. 求next数组
const nextArr = getNextArr(p);
// 类似求next数组,求匹配位置
// pIndex 模式串
let pIndex = 0;
for(let sIndex = 0; sIndex < s.length; sIndex++)
// 1.必须先判断不相等时,模式串回退
while(pIndex > 0 && s[sIndex] !== p[pIndex])
pIndex = nextArr[pIndex - 1];
// 2.如果相等,继续比较
if (s[sIndex] === p[pIndex])
pIndex++;
// sIndex已经在for中++了
// 3.更新next数组
// 变成了判断是否到头
if (pIndex === p.length)
return sIndex - p.length + 1;
return -1;
;
// 计算next数组
// s = 'aabaabaaf'
// p = 'aabaaf';
// nextArr = [ 0, 1, 0, 1, 2, 0 ];
function getNextArr(p)
const nextArr = [];
// pIndex 指向了前缀的末位
let pIndex = 0;
// 1个字符 其最长相等前后缀为 0
nextArr[0] = 0;
// sIndex 指向了后缀的末位
for(let sIndex = 1; sIndex < p.length; sIndex++)
// 1.必须先判断不相等时,pIndex不断回退
while(pIndex > 0 && p.charAt(pIndex) !== p.charAt(sIndex))
// 难点
pIndex = nextArr[pIndex - 1];
// 2.相等时
if (p.charAt(pIndex) === p.charAt(sIndex))
pIndex++;
// sIndex已经在for中++了
// 3. 更新nextArr
nextArr[sIndex] = pIndex;
return nextArr;
以上是关于28. 实现 strStr()简单暴力KMP的主要内容,如果未能解决你的问题,请参考以下文章
leetcode28.实现strStr()(暴力拆解,双指针,KMP算法)
LeetCode 28. Implement strStr()