打怪升级之旅之旅第7天

66 阅读2分钟

人生就是不断失去的过程

穆勒退役了 内马尔一年多没看过他踢球了

题目描述 vscode只有英文描述

Given a string s, return the longest palindromic substring in s.

Example 1:

Input: s = "babad"
Output: "bab"
Explanation: "aba" is also a valid answer.

Example 2:

Input: s = "cbbd"
Output: "bb"

 

Constraints:

  • 1 <= s.length <= 1000
  • s consist of only digits and English letters.

暴力破解


/**
 * 
 * @param {string} s 
 * @param {number} left 
 * @param {number} right 
 */
function getPassCheckString (s, left, right)
{
  while(left >=0 && right < s.length && s[left] === s[right]){
    left--
    right++
  }
  // subSting 不包含 end 打破while 最后一次一定是不满足回文子串的要求的
  return s.substring(left+1, right)
}

/**
 * homeliness solution
 * 找出最长回文子串
 * 给你一个字符串 s,找到 s 中最长的回文子串。
 * 如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
 * @param {string} s 
 * @return {string}
 * left right
 * 
 */
const longestPalindrome = function (s)
{
  let ans = ''
  for (let i = 0; i < s.length; i++) {
    // 回文串为奇数
    let str = getPassCheckString(s, i - 1, i + 1)
    if (str.length > ans.length) ans = str
    // 回文串为偶数
    str = getPassCheckString(s, i - 1, i)
    if (str.length > ans.length) ans = str
  }
  return ans
}

manacher algorithm

function longestPalindrome(s: string): string {
  //  manacher algorithm
  let sn = ["^", ...[...s].join("#"), "$"]
  let len = sn.length
  let p = new Array(sn.length).fill(0)
  let c = 0 // 当前中心点的位置
  let r = 0 // r 右边界 利用回文串的对称性
  let max = 0
  let ans = ""
  for (let i = 0; i < len - 1; i++) {
    // 如果当前的i 还在对称中心的边界中 表示它已经有一个最小值 即在对称中心右边的值 这样就可以知道 i的最小对称数
    if (i < r) p[i] = Math.min(r - i, p[2 * c - i])
    // 直接比较
    while (sn[i - p[i] - 1] === sn[i + p[i] + 1]) p[i]++
    // 就表示 已i为中心的边界 大于以c为中心的边界 更新 c 和 r
    if (p[i] + i > r) {
      r = p[i] + i
      c = i
    }
    if (p[i] >= max) {
      max = p[i]
      let start = i - max
      let end = i + max + 1
      let str = sn.slice(start, end).join("").replace(/#/g, "")
      if (str.length >= ans.length) ans = str
    }
  }

  return ans
}

image.png

Baybay!!