Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
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:
- Build a 2D prefix sum array where
dp[i][j]represents the count of characterjup to indexi - For each query, calculate character frequencies in the substring using prefix sums
- Count characters with odd frequencies
- 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.
