算法--最长回文串

123 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情

题目

leetcode 409. 最长回文串 难度:简单

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

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

示例 1:

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

示例 2:

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

提示:

1 <= s.length <= 2000

s 只由小写 和/或 大写英文字母组成

题解

「回文串」是指倒序后和自身完全相同的字符串,即具有关于中心轴对称的性质。观察发现,当回文串长度为偶数时,则所有字符都出现了偶数次;当回文串长度为奇数时,则位于中心的字符出现了奇数次,其余所有字符出现偶数次;

以回文中心为分界线,对于回文串中左侧的字符,在右侧对称的位置也会出现同样的字符。例如在字符串 "abba" 中,回文中心是 "ab|ba" 中竖线的位置,而在字符串 "abcba" 中,回文中心是 "ab(c)ba" 中的字符 "c" 本身。我们可以发现,在一个回文串中,只有最多一个字符出现了奇数次,其余的字符都出现偶数次。

我们可以将每个字符使用偶数次,使得它们根据回文中心对称。在这之后,如果有剩余的字符,我们可以再取出一个,作为回文中心。

var longestPalindrome = function(s) {
    const map = new Map();
    for (let i = 0; i < s.length; i++) {
        map.set(s[i], (map.get(s[i]) ?? 0) + 1);
    }
    let bothSide = 0;
    let center = 0;
    map.forEach(value => {
        if (value % 2 === 0) {
            bothSide += value;
        } else {
            center = 1;
            bothSide += --value;
        }
    })
    return bothSide + center;
};


代码详解

统计字符串中各个字符出现的次数 遍历map

  1. 如果字符出现偶数次,那么一定可以构成回文字符串的一部分,直接累加字符的长度即可
  2. 如果字符都出现奇数次,那么将字符出现的次数减去一,使它出现的次数为偶数次,然后加起来
  3. 因为回文字符串的长度可以为奇数,当字符串中存在出现奇数次的字符时,需要将结果加1,表示为最中间的字符