Can Make Palindrome from Substring in Python

Given a string s, we need to determine if substrings can be made into palindromes after performing certain operations. For each query [left, right, k], we can rearrange the substring s[left:right+1] and replace up to k characters. The goal is to check if a palindrome is possible after these operations.

The key insight is that in a palindrome, at most one character can have an odd frequency (the middle character). So we need to count characters with odd frequencies and see if we can fix them with our allowed replacements.

Algorithm

We'll use a prefix sum approach to efficiently count character frequencies in any substring:

  1. Build a 2D prefix sum array where dp[i][j] represents the count of character j up to index i
  2. For each query, calculate character frequencies in the substring using prefix sums
  3. Count characters with odd frequencies
  4. Check if half of odd-frequency characters is ? k (we can replace pairs to make them even)

Implementation

class Solution:
    def solve(self, dp, query):
        left, right, k = query
        right += 1
        left += 1
        
        # Count characters with odd frequencies
        odd_count = 0
        for i in range(26):
            char_count = dp[right][i] - dp[left-1][i]
            odd_count += char_count % 2
        
        # We need to replace odd_count//2 characters to make palindrome possible
        return odd_count // 2 <= k
    
    def make_dp(self, dp, s):
        for i in range(1, len(s)):
            # Copy previous counts
            for j in range(26):
                dp[i][j] = dp[i-1][j]
            # Increment count for current character
            dp[i][ord(s[i]) - ord('a')] += 1
    
    def canMakePaliQueries(self, s, queries):
        n = len(s)
        # Add space at beginning for 1-indexed access
        s = " " + s
        
        # Create prefix sum array
        dp = [[0 for _ in range(26)] for _ in range(n + 1)]
        self.make_dp(dp, s)
        
        # Process each query
        result = []
        for query in queries:
            result.append(self.solve(dp, query))
        
        return result

# Test the solution
solution = Solution()
s = "abcda"
queries = [[3,3,0],[1,2,0],[0,3,1],[0,3,2],[0,4,1]]
print(solution.canMakePaliQueries(s, queries))
[True, False, False, True, True]

How It Works

Let's trace through the example with string "abcda":

  • Query [3,3,0]: Substring is "d" (1 character) ? Already a palindrome ? True
  • Query [1,2,0]: Substring is "bc" ? 2 odd frequencies, need 1 replacement but k=0 ? False
  • Query [0,3,1]: Substring is "abcd" ? 4 odd frequencies, need 2 replacements but k=1 ? False
  • Query [0,3,2]: Substring is "abcd" ? 4 odd frequencies, need 2 replacements and k=2 ? True
  • Query [0,4,1]: Substring is "abcda" ? 2 odd frequencies, need 1 replacement and k=1 ? True

Time Complexity

The preprocessing takes O(n × 26) time, and each query is answered in O(26) time. Overall complexity is O(n + q) where q is the number of queries.

Conclusion

This solution efficiently determines palindrome possibility by counting odd-frequency characters in substrings. The prefix sum approach allows fast query processing, making it suitable for multiple queries on the same string.

Updated on: 2026-03-25T08:25:04+05:30

236 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements