目录
利用字符串所有字符构造 k 个回文串 — 问题分析与解题思路
利用字符串所有字符构造 k 个回文串 — 问题分析与解题思路
题目描述
给定一个字符串 s
和一个整数 k
,判断是否可以使用字符串 s
中 所有字符 构造出恰好 k
个 非空回文字符串。
要求:
- 这
k
个回文字符串必须使用s
中所有字符(没有剩余字符)。 - 每个回文串都非空。
- 判断是否存在这样一种构造方案。
题目示例
示例 1
输入:s = "annabelle", k = 2
输出:true
解释:可以构造两个回文串,组合方案示例:
- "anna" + "elble"
- "anbna" + "elle"
- "anellena" + "b"
示例 2
输入:s = "leetcode", k = 3
输出:false
解释:无法用 s 中所有字符构造 3 个回文串。
示例 3
输入:s = "true", k = 4
输出:true
解释:可以让 s 中每个字符单独作为回文串。
解题分析
要解决这个问题,首先需要理解回文字符串的本质特征:
- 回文串的定义:正读和反读相同。
- 对于 偶数长度的回文串,所有字符的出现次数必须是偶数(配对成对出现)。
- 对于 奇数长度的回文串,只有一个字符可以出现奇数次,其余字符都是偶数次。
利用这个特性,我们可以推断:
- 构造 k 个回文串时,每个回文串最多包含一个奇数次数的字符。
- 因此,字符串中所有出现奇数次数的字符数目,至少不能大于 k,否则无法分配每个奇数字符到不同的回文串中。
- 同时,k 不能大于 s 的长度,因为回文串必须非空。
核心判断条件
- 统计奇数次数字符数:计算字符串中出现次数为奇数的字符数量,记为
oddCount
。 - 判断奇数字符数是否超过 k:如果
oddCount > k
,那么无法构造 k 个回文串。 - 判断 k 是否超过字符串长度:如果
k > len(s)
,也无法构造。
只有满足以上条件,才可能构造出 k 个回文串。
解题方法(代码实现)
使用 Python 的 collections.Counter
统计字符频次:
from collections import Counter
class Solution:
def canConstruct(self, s: str, k: int) -> bool:
# 不能构造超过字符串长度的回文串
if k > len(s):
return False
count = Counter(s)
# 统计出现次数为奇数的字符个数
oddCount = sum(1 for v in count.values() if v % 2 == 1)
# 如果奇数字符数超过 k,无法构造
return oddCount <= k
代码逻辑解析
Counter(s)
统计了 s 中每个字符的出现次数。- 用一个生成器表达式遍历统计奇数次数的字符个数。
- 判断奇数字符数是否不超过 k。
- 提前判断 k 是否大于字符串长度,提高效率。
分析与比较
- 时间复杂度:O(n),n 为字符串长度,统计字符频次和遍历次数均为线性。
- 空间复杂度:O(1) 或 O(m),m 为字符集大小(常量范围,如 ASCII 字符),因为
Counter
统计有限字符。
该方法无需复杂动态规划或回溯,逻辑简明,适合面试或竞赛。
示例说明
示例 1: s = "annabelle", k = 2
- 字符频次统计(简略):a(3), n(2), b(1), e(2), l(2)
- 奇数次数字符:a(3), b(1) → 两个奇数
- k = 2,满足条件
oddCount <= k
,返回 True。
示例 2: s = "leetcode", k = 3
- 字符频次:l(1), e(3), t(1), c(1), o(1), d(1)
- 奇数次数字符:l, e, t, c, o, d → 6 个奇数
- k = 3,不满足条件,返回 False。
示例 3: s = "true", k = 4
- s 长度=4,k=4
- 每个字符可以单独作为回文串
- 返回 True。
总结
本题的难点在于对回文串字符分布的理解。通过对奇数次数字符数的统计,巧妙地将问题转化为简单的数学条件判断,大大降低了算法复杂度。
掌握此类思路,能够帮助我们快速解决类似字符分组构造问题。希望这篇博客能帮助你更好地理解并应对相关题目!