Construct K Palindrome Strings

Updated on 19 May, 2025
Construct K Palindrome Strings header image

Problem Statement

Given a string s and an integer k, you are tasked with determining whether it is possible to use all characters of the string s to form exactly k non-empty palindromes. A palindrome is a sequence of characters which reads the same backward as forward. The result is to output true if such a construction is possible, otherwise output false.

Examples

Example 1

Input:

s = "annabelle", k = 2

Output:

true

Explanation:

You can construct two palindromes using all characters in s.
Some possible constructions "anna" + "elble", "anbna" + "elle", "anellena" + "b"

Example 2

Input:

s = "leetcode", k = 3

Output:

false

Explanation:

It is impossible to construct 3 palindromes using all the characters of s.

Example 3

Input:

s = "true", k = 4

Output:

true

Explanation:

The only possible solution is to put each character in a separate string.

Constraints

  • 1 <= s.length <= 105
  • s consists of lowercase English letters.
  • 1 <= k <= 105

Approach and Intuition

Step-by-Step Analysis

  1. Determine Character Frequency:

    • First, count the frequency of each character in the string s. This helps to understand how many times each character appears, which is crucial because in palindromes, most characters need to appear an even number of times (except possibly one character which can appear an odd number of times if the length of the palindrome is odd).
  2. Check Number of Odd Frequency Characters:

    • Palindromes can have at most one character with an odd count. Calculate the number of characters in s that have an odd frequency. This number will indicate the minimum number of separate palindromes we might need if each odd-frequency character is placed in a different palindrome.
  3. Evaluate k relative to Found Limits:

    • Based on the count of odd frequency characters (let's say odd_count), consider:
      • If k < odd_count: It's impossible to satisfy the palindrome condition with k palindromes as there aren't enough palindromes to allocate the odd characters individually.
      • If k > s.length: It implies trying to stretch fewer characters over more slots that each need at least one character. Hence, it can't be done.
      • If odd_count <= k <= s.length: In this case, there are enough palindromes to place the odd-frequency characters, and there are adequate characters to populate k non-empty strings.

Example Analysis

For a better understanding, consider the provided examples:

  • Example 1: "annabelle", k=2

    • Character counts- {'a': 2, 'n': 2, 'e': 2, 'l': 2, 'b': 1} - 'b' is the only character with odd frequency.
    • Since k=2 and there is only 1 odd frequency, it's possible to create 2 palindromes, one could contain the odd 'b'.
  • Example 2: "leetcode", k=3

    • Character counts- {'l': 1, 'e': 3, 't': 1, 'c': 1, 'o': 1, 'd': 1}
    • There are 5 characters with odd frequencies (more than k). It's impossible to arrange them into 3 palindromes while using up all characters.
  • Example 3: "true", k=4

    • Every character appears once. Odd count equals the number of characters equals k.
    • Each character forms a non-empty palindrome string. Hence, it's perfectly possible.

From this pattern, it's evident that the feasibility of forming k palindromes hinges significantly on the comparison between the count of characters with odd frequencies and k. This analysis, while direct, utilizes character count intricacies to deduce the feasibility quickly without constructing the palindromes.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    bool canMakePalindrome(string str, int maxPalindromes) {
        if (str.length() < maxPalindromes) return false;
        if (str.length() == maxPalindromes) return true;
        
        int frequencyMask = 0;
        
        for (char c : str) {
            frequencyMask ^= 1 << (c - 'a');
        }
        
        int oddCharacterCount = __builtin_popcount(frequencyMask);
        
        return oddCharacterCount <= maxPalindromes;
    }
};

The provided C++ solution defines a method to determine whether it's possible to form up to maxPalindromes palindrome strings from the given string str. Below is a tailored summary of the process the code follows:

  • The code first checks if the length of the string str is less than maxPalindromes. If true, it's not possible to make the required number of palindromes, hence it returns false.
  • Next, it checks if the length of str is exactly equal to maxPalindromes. Each character could potentially be its own palindrome, so it returns true.
  • It initializes an integer frequencyMask to track the frequency of characters by leveraging bit manipulation. For each character in str, it toggles the corresponding bit in the frequencyMask.
  • The function __builtin_popcount is used to calculate the number of bits set to 1 in the frequencyMask, which represents the count of characters that have an odd frequency.
  • Finally, the function checks if the number of characters with odd frequencies (oddCharacterCount) is less than or equal to the allowed number of palindrome strings (maxPalindromes). If the condition holds, it returns true; otherwise, false.

This efficient approach makes good use of bitwise operations to keep track of character frequencies, and it evaluates conditions for palindrome formation with minimal computational overhead.

java
class Solution {

    public boolean canFormPalindrome(String text, int maxParts) {
        // Validate constraints related to string length and parts count
        if (text.length() < maxParts) return false;
        if (text.length() == maxParts) return true;

        // Setup bit-mask for characters
        int charMask = 0;

        // Populate charMask based on occurrences of each character
        for (char character : text.toCharArray()) {
            charMask ^= 1 << (character - 'a');
        }

        // Check that the count of characters with odd occurrences is within limit
        return Integer.bitCount(charMask) <= maxParts;
    }
}

The provided Java solution addresses the problem of determining if a given string can be divided into maxParts number of palindrome substrings. Here’s a breakdown of the function canFormPalindrome:

  1. The function first checks if the length of the string text is less than maxParts. If it is, the function returns false because it's not possible to divide the string into more parts than its length.
  2. If text.length() equals maxParts, each character of the string must itself be a palindrome substring. Thus, the function returns true.
  3. A charMask integer is initialized to zero. This variable is used to track the frequency of each character, determining whether the frequency is odd or even.
  4. A loop iterates through each character in the string, updating the charMask using a bitwise XOR operation with a shifted bit. This operation toggles bits in charMask depending on the character's presence, effectively counting the number of characters that appear an odd number of times.
  5. Finally, the function returns true if the number of characters that have an odd bit count in the charMask does not exceed maxParts. This condition allows for the construction of at most maxParts palindromes.

This approach efficiently checks the feasibility of constructing the required number of palindrome substrings using bitwise manipulation, thus optimizing the process of counting character occurrences.

python
class Solution:
    def canForm(self, string: str, num: int) -> bool:
        # Validate length conditions
        if len(string) < num:
            return False
        if len(string) == num:
            return True
        # Setup character frequency tracking
        odd_freq = 0

        # Calculate frequency of odd occurrences
        for character in string:
            odd_freq ^= 1 << (ord(character) - ord('a'))
        # Check if we can distribute odd frequencies within the given limit
        return bin(odd_freq).count("1") <= num

The solution addresses the problem of determining whether it is possible to construct num palindrome strings from the input string. It uses an efficient bitwise operation approach to handle the characters frequency and check palindrome possibilities. Here's the strategy implemented in the Python code:

  1. First, verify if the length of the given string is less than num. If it is, it's impossible to construct num palindromes, thus return False.
  2. If the length of the string equals num, each character can potentially form a palindrome individually, so return True.
  3. Initialize a counter odd_freq to track the frequency of characters with an odd number of occurrences.
  4. Process each character in the string:
    • Toggle the respective bit for each character in a bitmask (odd_freq) using XOR operation. This effectively counts whether each character has an even or odd frequency using bit positions.
  5. Finally, convert the odd_freq bitmask into a binary string and count the number of '1's. If this count (number of characters with odd frequencies) is less than or equal to num, return True; otherwise, return False.

This algorithm effectively checks the potential to form palindromes based on the character frequencies' parity, ensuring that the number of palindromes (num) can contain the characters with odd frequency. The bitwise operations provide a compact and efficient way to count character occurrences and their modality (odd/even).

Comments

No comments yet.