题目描述
思路解析动画文字版
思路一句话:先数每个字母频次,把成对的部分累加;有剩单的就给中心 +1。下面一步步演给你看。
开始前:频次表是空的,答案长度 = 0。我们先把每个字母出现几次数清楚。
指针走到下标 0,这一格的字母是 'a'。把它记进频次表。
'a' 的次数加一,现在 cnt['a'] = 1。继续往后数。
指针走到下标 1,这一格的字母是 'b'。把它记进频次表。
'b' 的次数加一,现在 cnt['b'] = 1。继续往后数。
指针走到下标 2,这一格的字母是 'c'。把它记进频次表。
'c' 的次数加一,现在 cnt['c'] = 1。继续往后数。
指针走到下标 3,这一格的字母是 'c'。把它记进频次表。
'c' 的次数加一,现在 cnt['c'] = 2。继续往后数。
指针走到下标 4,这一格的字母是 'c'。把它记进频次表。
'c' 的次数加一,现在 cnt['c'] = 3。继续往后数。
指针走到下标 5,这一格的字母是 'c'。把它记进频次表。
'c' 的次数加一,现在 cnt['c'] = 4。继续往后数。
指针走到下标 6,这一格的字母是 'd'。把它记进频次表。
'd' 的次数加一,现在 cnt['d'] = 1。继续往后数。
指针走到下标 7,这一格的字母是 'd'。把它记进频次表。
'd' 的次数加一,现在 cnt['d'] = 2。继续往后数。
数完了:'a' 出现 1 次,'b' 出现 1 次,'c' 出现 4 次,'d' 出现 2 次。接下来按字母看能凑几对。
字母 'a' 只出现 1 次,凑不成对(红色),暂时贡献 0 个长度。它可能留给中心。
'a' 出现奇数次,凑完对后还剩一个落单的(红色)。先记下:最后可以把它(或任意一个落单字母)放到回文正中心。
字母 'b' 只出现 1 次,凑不成对(红色),暂时贡献 0 个长度。它可能留给中心。
'b' 也是奇数次、又剩一个落单的。但回文中心只有一个位置,已经占了,所以这次不再加长。
字母 'c' 出现 4 次,能凑出 2 对(绿色这些),左右对称各放一半,答案长度加 4,现在 = 4。
字母 'd' 出现 2 次,能凑出 1 对(绿色这些),左右对称各放一半,答案长度加 2,现在 = 6。
最后一步:因为有落单字母,把其中一个放到回文正中心,长度再 +1。最长回文串长度 = 7。
三个边界:全单字母只取 1、全成对不加中心、单字符本身即回文。
三个高频追问:成对的原因、空串边界、用集合的等价写法。
参考代码
def longestPalindrome(s): from collections import Counter cnt = Counter(s) # 数每个字母出现几次 ans = 0 odd = False # 是否存在奇数次字母 for c in cnt.values(): ans += c // 2 * 2 # 成对的部分贡献长度 if c % 2 == 1: odd = True # 有落单字母 return ans + (1 if odd else 0) # 落单的放中心 +1复杂度
- 时间:O(n),扫一遍字符串数频次,再扫一遍频次表,都是线性
- 空间:O(k),频次表只存出现过的字母,字母集合大小有限(最多 128)
易错点
面试追问把动画讲成自己的话
追问为什么除了中心,其它字母都要成对?
追问如果字符串为空会怎样?
追问能不能不用计数表?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
独一无二的出现次数
LeetCode 1207 · 简单 · 沿着 哈希套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题