在问 · 算法题解

409. 最长回文串

题目描述

输入一个只含大小写英文字母的字符串 s。用 s 中的字母(每个字母最多用一次,可以不全用)重新排列,组成一个回文串。

大小写视为不同的字符,例如 "Aa" 不是回文串。

返回能组成的最长回文串的长度。

示例 1
输入:s = "abccccdd"
输出:7

解释:可以组成 "dccaccd",长度为 7。

示例 2
输入:s = "a"
输出:1

解释:单个字母本身就是回文。

数据范围

  • 1 <= s.length <= 2000
  • s 只含大写和小写英文字母

解题思路

回文串两侧对称,每种字符成对使用,最多只有中间一个字符可以单独出现。统计每个字符的次数 v,贪心地用掉 v // 2 * 2 个;只要有任何一个字符次数为奇数,就把它的一个放在正中间,答案加 1。

为什么正确

res 始终是已处理字符能提供的成对字符总数,odd 表示是否已有奇数次的字符可以放中间。

复杂度分析

时间 O(n),空间 O(字符集大小)。

易错点

奇数次的字符不是完全不能用,而是要用掉其中的偶数个;中间只能放一个,所以 odd 只加一次。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def longestPalindrome(self, s: str) -> int:
        cnt = {}
        for ch in s:
            cnt[ch] = cnt.get(ch, 0) + 1
        res = 0
        odd = 0
        for v in cnt.values():
            res += v // 2 * 2
            if v % 2 == 1:
                odd = 1
        return res + odd

载入编辑器,自己跑一遍 →

贪心 专题的其他题目

查看 贪心 全部题目 →