Today’s problem
https://leetcode.com/problems/construct-k-palindrome-strings/description/
Intuition
A palindrome can have at most one character with an odd count. Therefore, to create $k$ palindrome strings, there must be at most $k$ characters in string $s$ with an odd count.
Additionally, since there are at most 26 different characters, if $26 \leq k$, the result must be true. However, if the length of $s$ is less than $k$, it would be false.
To prove this, let the number of characters with odd counts be $cntO$, and let the count of all remaining characters be $2 \times cntE$.
If all character counts are even, we can always create palindrome strings as long as $k \leq N$, where $N$ is the total length of $s$. This is because we can place one character on the leftmost side of a palindrome string and its duplicate on the rightmost side, preserving the palindrome structure.
Since $k \leq N$, it follows that $k \leq cntO + 2 \times cntE$. Thus, $k - cntO \leq 2 \times cntE$. This implies that all characters with odd counts can be used to form $cntO$ palindrome strings.
Now, we have already proved that if all character counts are even, we can always create palindrome strings as long as $k \leq N$, where $N$ is the total length of $s$. So in this case, if $cntO \le k$, the result would be ture, otherwise, it would be false.
Finally, the question reduces to the proposition that $k \leq N$ when all characters have even counts, which is always true.
Trick
Since there are at most 26 different characters, if $26 \leq k$, the result must be true.
Approach
Now we only need to calculate the occurence of every character and test whether the odd-count characters are less or equal to $k$ or not.
Complexity
-
Time complexity: $O(N)$, while N is the length of the string.
-
Space complexity: $O(1)$, while the count of 26 characters are stored.
Code
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
