LeetCode 28. 找出字符串中第一个匹配项的下标
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
示例 1: 输入: haystack = "hello", needle = "ll" 输出: 2
示例 2: 输入: haystack = "aaaaa", needle = "bba" 输出: -1
说明: 当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。 对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。
思路
KMP的经典思想就是:当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配。
要点:
-
什么是KMP
-
KMP有什么用
-
什么是前缀表
-
为什么一定要用前缀表
-
如何计算前缀表
-
前缀表与next数组
-
使用next数组来匹配
-
时间复杂度分析
-
构造next数组
-
使用next数组来做匹配
JavaScript 代码:
/*** @param {string} haystack* @param {string} needle* @return {number}*/var strStr = function(haystack, needle) {// KMPif (needle.length === 0)return 0;const getNext = (needle) => { // 获取needle的前缀表let next = [];let j = -1next[0] = jfor(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) // needle字符串遍历完成,即找到return (i - needle.length + 1);}return -1;};