今日题目
https://leetcode.com/problems/construct-k-palindrome-strings/description/
思路
一个回文串中,最多只能有一个字符的出现次数为奇数。因此,要构造 $k$ 个回文串,字符串 $s$ 中出现次数为奇数的字符最多只能有 $k$ 个。
此外,由于最多只有 26 种不同的字符,若 $26 \leq k$,结果一定为 true。但若 $s$ 的长度小于 $k$,则结果为 false。
下面进行证明。设出现次数为奇数的字符共有 $cntO$ 个,其余所有字符的总出现次数为 $2 \times cntE$。
若所有字符的出现次数均为偶数,只要 $k \leq N$(其中 $N$ 为 $s$ 的总长度),就一定能构造出回文串。这是因为我们可以将一个字符放在回文串最左侧,将其对应的重复字符放在最右侧,从而保持回文结构。
由于 $k \leq N$,可得 $k \leq cntO + 2 \times cntE$,即 $k - cntO \leq 2 \times cntE$。这意味着所有出现次数为奇数的字符可以各自构成一个回文串,共 $cntO$ 个。
我们已经证明:当所有字符出现次数均为偶数时,只要 $k \leq N$,就一定能构造回文串。因此,若 $cntO \le k$,结果为 true,否则为 false。
综上所述,问题最终归结为:当所有字符出现次数均为偶数时,$k \leq N$ 是否成立,而这一条件始终为 true。
技巧
由于最多只有 26 种不同字符,若 $26 \leq k$,结果一定为 true。
解题方法
只需统计每个字符的出现次数,再判断出现次数为奇数的字符数量是否不超过 $k$ 即可。
复杂度分析
-
时间复杂度:$O(N)$,其中 N 为字符串的长度。
-
空间复杂度:$O(1)$,仅需存储 26 个字符的计数。
代码
class Solution:
def canConstruct(self, s: str, k: int) -> bool:
cnt = [0] * 26
if len(s) < k:
return False
if k > 25:
return True
# The code that makes the code run very fast.
for ch in s:
cnt[ord(ch) - ord('a')] += 1
x = 0
for i in range(26):
if cnt[i] % 2 == 1:
x += 1
return x <= k
