持续创作,加速成长!这是我参与「掘金日新计划 · 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,表示为最中间的字符