KMP 算法子串匹配

366 阅读1分钟

leetCode:实现 strStr()

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。

示例 1:

输入: haystack = "hello", needle = "ll"
输出: 2

示例 2:

输入: haystack = "aaaaa", needle = "bba"
输出: -1

自己想出来的解

时间复杂度:O(mn) 空间复杂度:O(1)

const txt = 'I am dsadaabaabaaasda world'
const pattern = 'aabaabaaa'

console.log(match(pattern, txt))

function match(pattern, str) {
  if (!pattern) return 0
  else if (!str) return -1

  let k = 0

  for (let i = 0; i < str.length; i++) {
    if (str[i] === pattern[k]) {
      k++
      if (k === pattern.length) return i - j + 1
    } else {
      if (k !== 0) i -= k
      k = 0
    }
  }

  return -1
}

KMP 解

时间复杂度:O(m + n) 空间复杂度:O(m)

const txt = 'I am dsadaabaabaaasda world'
const pattern = 'aabaabaaa'

console.log(match(pattern, txt))

function match(pattern, str) {
  if (!str) return 0
  else if (!str) return -1

  let nextList = generateNextList(pattern)
  let j = 0

  for (let i = 0; i < str.length; i++) {
    if (str[i] === pattern[j]) {
      j++
    } else {
      while(j > 0) {
        j = nextList[j - 1]
        if (str[i] === pattern[j]) {
          j++
          break
        }
      }
    }

    if (j === pattern.length) return i - j + 1
    else if (str.length - 1 - i < pattern.length - j) return -1
  }

  return -1
}

function generateNextList(pattern) {
  let array = [0]
  let j = 0

  for (let i = 1; i < pattern.length; i++) {
    if (pattern[i] === pattern[j]) {
      j++
    } else {
      while(j > 0) {
        j = array[j - 1]
        if (pattern[i] === pattern[j]) {
          j++
          break
        }
      }
    }

    array.push(j)
  }

  return array
}

参考

1、B站:【soso字幕】汪都能听懂的KMP字符串匹配算法【双语字幕】