leetcode_1400 构造 K 个回文字符串

214 阅读2分钟

要求

给你一个字符串 s 和一个整数 k 。请你用 s 字符串中 所有字符 构造 k 个非空 回文串 。

如果你可以用 s 中所有字符构造 k 个回文字符串,那么请你返回 True ,否则返回 False 。

示例 1:

输入:s = "annabelle", k = 2
输出:true
解释:可以用 s 中所有字符构造 2 个回文字符串。
一些可行的构造方案包括:"anna" + "elble""anbna" + "elle""anellena" + "b"

示例 2:

输入:s = "leetcode", k = 3
输出:false
解释:无法用 s 中所有字符构造 3 个回文串。

示例 3:

输入:s = "true", k = 4
输出:true
解释:唯一可行的方案是让 s 中每个字符单独构成一个字符串。

示例 4:

输入:s = "yzyzyzyzyzyzyzy", k = 2
输出:true
解释:你只需要将所有的 z 放在一个字符串中,所有的 y 放在另一个字符串中。那么两个字符串都是回文串。

示例 5:

输入:s = "cr", k = 7
输出:false
解释:我们没有足够的字符去构造 7 个回文串。

提示:

  • 1 <= s.length <= 10^5
  • s 中所有字符都是小写英文字母。
  • 1 <= k <= 10^5

核心代码

class Solution:
    def canConstruct(self, s: str, k: int) -> bool:
        if k >= len(s):
            return k == len(s)
        from collections import Counter
        dic = Counter(s)

        s_odd = 0
        for val in dic.values():
            if val % 2:
                s_odd += 1
        return s_odd <= k

image.png

解题思路:首先处理一下比较简单的情况:如果 s 的长度和 k 相等,那么每个字符单独构成一个字符串,答案必然存在;如果 s 的长度比 k 要小,那么答案必不可能存在。
现在我们能保证 s 的长度大于 k。其次统计一下 s 里每种元素出现的个数:

  1. 如果一个元素出现次数为偶数次( k ),我们最少可以用 零个回文字符串,最多可以用 k 个回文字符串。
  2. 如果一个元素出现次数为奇数次( k ),那么为了处理这个元素,我们必然至少需要一个回文字符串,最多可以用 k 个回文字符串。 所以实际上对答案有影响的就是出现了奇数次的元素的个数,假设有 A 个元素的出现次数为奇数次,那么我们至少需要 A 个回文字符串。 对于其他的出现次数为偶数次的元素,我们可以将这偶数个字符包裹住已有的回文串,因此对回文串的个数没有影响。时间复杂度:O(N)空间复杂度:O(N)