Skip to content
On this page

最长回文串

leetcode 给定一个包含大写字母和小写字母的字符串  s ,返回通过这些字母构造成的 最长的回文串  。

在构造过程中,请注意 区分大小写 。比如  "Aa"  不能当做一个回文字符串。

js
输入:s = "abccccdd"
输出:7
解释: 我们可以构造的最长的回文串是"dccaccd", 它的长度是 7

输入:s = "a"
输入:1

输入:s = "bb"
输入: 2

思路

解体的关键在于计算有多少对相同的字符。就类似于打牌,抽到一对牌就打出来。当所有的牌都抽完了,手里如果还有剩余的未成对的牌,我能还能抽出一张

这里我用 map 来存放抽到的牌,如果当前抽到的牌已经在手里有了,那么把手里的那个牌和当前的牌凑成一对打出来,结果+2。最后如果手里还有牌,结果+1


  1. 回文串的特点是都是成双成对的(除了奇数回文串中心节点之外,其它字符都是成双成对的)
  2. 现在给我们一个字符串,让我们用这个字符串来构建回文串
  3. 关键在于计算有多少对相同的字符

代码

js
/**
 * @param {string} s
 * @return {number}
 */
var longestPalindrome = function (s) {
  let map = new Map();
  let sum = 0;
  for (let char of s) {
    if (map.has(char)) {
      sum += 2;
      map.delete(char);
    } else {
      map.set(char);
    }
  }

  // 如果手上还有牌,则 + 1
  let temp = map.size > 0 ? 1 : 0;
  return sum + temp;
};

最长回文子串

给你一个字符串 s,找到 s 中最长的回文子串。

js
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

输入:s = "cbbd"
输出:"bb"
js
/**
 * @param {string} s
 * @return {string}
 */
var longestPalindrome = function (s) {
  let res = s[0];
  let len = s.length;
  for (let i = 1; i < len; i++) {
    let [l, r] = [i, i];
    // 左回文 bb 情况
    while (l > 0 && s[i] === s[l - 1]) l--;

    // 右回文
    while (r < len - 1 && s[i] === s[r + 1]) r++;

    // 左右回文 bab 情况
    while (l > 0 && r < len - 1 && s[l - 1] === s[r + 1]) {
      l--;
      r++;
    }

    if (l < r) {
      let cur = s.slice(l, r + 1);
      res = cur.length > res.length ? cur : res;
    }
  }

  return res;
};

Released under the MIT License.