Computer >> Computer tutorials >  >> Programming >> Python

Can Make Palindrome from Substring in Python


Suppose we have a string s, we have to make queries on substrings of s. For each query queries[i], there are three parts [left, right, k], we may rearrange the substring s[left], ..., s[right], and then choose up to k of them to replace with any lowercase English letter. If the substring is possible to be a palindrome after the operations mentioned above, the result of the query is true. Otherwise false. We have to find an array answer[], where answer[i] is the result of the i-th query queries[i].

For example, if the input is “abcda”, queries is like [[3,3,0],[1,2,0],[0,3,1],[0,3,2],[0,4,1]], then the output will be [true, false, false, true, true]

To solve this, we will follow these steps −

  • Define a method called solve, this will take dp matrix, and q. This will work like below −
  • l := q[0], r := q[1], k := q[2], then increase l and r by 1, one := 0
  • for i in range 0 to 25
    • one := one + (dp[r, i] – dp[l – 1, i]) mod 2
  • return true, when integer division of one / 2 <= k, otherwise false
  • Define another method called makeDP(), this will take dp matrix and s, this will work like below −
  • for i in range 0 to length of s
    • for j in range 0 to 25
      • dp[i, j] := dp[i – 1, j]
    • increase dp[i, ASCII of s[i] – ASCII of ‘a’] by 1
  • The main method will be like −
  • n := size of the string s, s := “ ” concatenate s
  • dp := a matrix of order (n + 1) x 26, and fill this with 0
  • call makeDP(dp, s)
  • res := an array of size same as length of q, and fill this with false
  • for i in range 0 to length of q – 1
    • res[i] := solve(dp, q[i])
  • return res

Example(Python)

Let us see the following implementation to get a better understanding −

class Solution(object):
   def solve(self,dp,q):
      l = q[0]
      r = q[1]
      k = q[2]
      r+=1
      l+=1
      #arr = [ 0 for i in range(26)]
      one = 0
      for i in range(26):
         one += (dp[r][i]-dp[l-1][i])%2
      return one//2<=k
   def make_dp(self,dp,s):
      for i in range(1,len(s)):
         for j in range(26):
            dp[i][j] = dp[i-1][j]
         dp[i][ord(s[i])-ord('a')]+=1
   def canMakePaliQueries(self, s, q):
      n = len(s)
      s = " "+s
      dp = [[0 for i in range(26)] for j in range(n+1)]
      self.make_dp(dp,s)
      res = [False for i in range(len(q))]
      for i in range(len(q)):
         res[i] = self.solve(dp,q[i])
      return res
ob = Solution()
print(ob.canMakePaliQueries("abcda", [[3,3,0],[1,2,0],[0,3,1],[0,3,2],[0,4,1]]))

Input

"abcda"
[[3,3,0],[1,2,0],[0,3,1],[0,3,2],[0,4,1]]

Output

[True, False, False, True, True]