Check if a substring can be Palindromic by replacing K characters for Q queries

Given a string str and Q queries in form of [L, R, K], the task is to find whether characters from the string from [L, R] with at most K changes are allowed can be rearranged to make string palindromic or not. For each query, print “YES” if it can become a palindromic string else print “NO”.
Examples: 

Input: str = “GeeksforGeeks”, Q = { { 1, 5, 3 }, { 5, 7, 0 }, { 8, 11, 3 }, {3, 10, 5 }, { 0, 9, 5 } } 
Output: 
YES 
NO 
YES 
YES 
YES 
Explanation: 
queries[0] : substring = “eeksf”, could be changed to “eekee” which is palindrome. 
queries[1] : substring = “for”, is not palindrome and can’t be made palindromic after replacing atmost 0 character.. 
queries[2] : substring = “Gee”, could be changed to “GeG” which is palindrome. 
queries[3] : substring = “ksforGee”, could be changed to “ksfoofsk” which is palindrome. 
queries[4] : substring = “GeeksforGe”, could be changed to “GeeksskeeG” which is palindrome.
Input: str = “abczwerte”, Q = { { 3, 7, 4 }, { 1, 8, 10 }, { 0, 3, 1 } } 
Output: 
YES 
YES 
NO 

Approach: This problem can be solved using Dynamic Programming.  

count =  dp[i][right] - dp[i][left] + (str[left] == i + 'a').

Below is the implementation of the above approach: 
 

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find whether string can
// be made palindromic or not for each queries
void canMakePaliQueries(
    string str,
    vector<vector<int> >& Q)
{
    int n = str.length();
 
    // To store the count of ith character
    // of substring str[0...i]
    vector<vector<int> > dp(
        26,
        vector<int>(n, 0));
 
    for (int i = 0; i < 26; i++) {
 
        // Current character
        char currentChar = i + 'a';
        for (int j = 0; j < n; j++) {
 
            // Update dp[][] on the basis
            // recurrence relation
            if (j == 0) {
                dp[i][j]
                    = (str[j] == currentChar);
            }
            else {
                dp[i][j]
                    = dp[i][j - 1]
                      + (str[j] == currentChar);
            }
        }
    }
 
    // For each queries
    for (auto query : Q) {
        int left = query[0];
        int right = query[1];
        int k = query[2];
 
        // To store the count of
        // distinct character
        int unMatchedCount = 0;
        for (int i = 0; i < 26; i++) {
 
            // Find occurrence of i + 'a'
            int occurrence
                = dp[i][right]
                  - dp[i][left]
                  + (str[left] == (i + 'a'));
 
            if (occurrence & 1)
                unMatchedCount++;
        }
 
        // Half the distinct Count
        int ans = unMatchedCount / 2;
 
        // If half the distinct count is
        // less than equals to K then
        // palindromic string can be made
        if (ans <= k) {
            cout << "YES\n";
        }
        else {
            cout << "NO\n";
        }
    }
}
 
// Driver Code
int main()
{
    // Given string str
    string str = "GeeksforGeeks";
 
    // Given Queries
    vector<vector<int> > Q;
    Q = { { 1, 5, 3 }, { 5, 7, 0 },
 { 8, 11, 3 }, { 3, 10, 5 },
{ 0, 9, 5 } };
 
    // Function call
    canMakePaliQueries(str, Q);
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach
class GFG{
 
// Function to find whether String can be
// made palindromic or not for each queries
static void canMakePaliQueries(String str,
                               int [][]Q)
{
    int n = str.length();
 
    // To store the count of ith character
    // of subString str[0...i]
    int [][]dp = new int[26][n];
 
    for(int i = 0; i < 26; i++)
    {
        
       // Current character
       char currentChar = (char)(i + 'a');
       for(int j = 0; j < n; j++)
       {
        
          // Update dp[][] on the basis
          // recurrence relation
          if (j == 0)
          {
              dp[i][j] = (str.charAt(j) ==
                          currentChar) ? 1 : 0;
          }
          else
          {
              dp[i][j] = dp[i][j - 1] +
                         ((str.charAt(j) ==
                           currentChar) ? 1 : 0);
          }
       }
    }
 
    // For each queries
    for(int []query : Q)
    {
       int left = query[0];
       int right = query[1];
       int k = query[2];
        
       // To store the count of
       // distinct character
       int unMatchedCount = 0;
       for(int i = 0; i < 26; i++)
       {
            
          // Find occurrence of i + 'a'
          int occurrence = dp[i][right] -
                           dp[i][left] +
                           (str.charAt(left) ==
                           (i + 'a') ? 1 : 0);
           
          if (occurrence % 2 == 1)
              unMatchedCount++;
       }
        
       // Half the distinct Count
       int ans = unMatchedCount / 2;
        
       // If half the distinct count is
       // less than equals to K then
       // palindromic String can be made
       if (ans <= k)
       {
           System.out.print("YES\n");
       }
       else
       {
           System.out.print("NO\n");
       }
    }
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given a String str
    String str = "GeeksforGeeks";
 
    // Given Queries
    int [][]Q = { { 1, 5, 3 },
                  { 5, 7, 0 },
                  { 8, 11, 3 },
                  { 3, 10, 5 },
                  { 0, 9, 5 } };
                   
    // Function call
    canMakePaliQueries(str, Q);
}
}
 
// This code is contributed by gauravrajput1
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program for
# the above approach
 
# Function to find whether
# string can be made palindromic
# or not for each queries
def canMakePaliQueries(str, Q):
    n = len(str)
 
    # To store the count of
    # ith character of substring
    # str[0...i]
    dp = [[0 for i in range(n)]
             for j in range(26)]\
     
    for i in range(26):
 
        # Current character
        currentChar = chr(i + ord('a'))
         
        for j in range(n):
 
            # Update dp[][] on the basis
            # recurrence relation
            if(j == 0):
                dp[i][j] = (str[j] ==
                            currentChar)
            else:
                dp[i][j] = dp[i][j - 1] +
                           (str[j] == currentChar)
 
    # For each queries
    for query in Q:
        left = query[0]
        right = query[1]
        k = query[2]
 
        # To store the count of
        # distinct character
        unMatchedCount = 0
 
        for i in range(26):
 
            # Find occurrence of
            # i + 'a'
            occurrence = dp[i][right] -
                         dp[i][left] +
                         (str[left] ==
                          chr(i + ord('a')))
                 
            if(occurrence & 1):
                unMatchedCount += 1
 
         # Half the distinct Count
        ans = int(unMatchedCount / 2)
 
        # If half the distinct count is
        # less than equals to K then
        # palindromic string can be made
        if(ans <= k):
            print("YES")
        else:
            print("NO")
 
# Driver Code
 
# Given string str
str = "GeeksforGeeks"
 
# Given Queries
Q = [[1, 5, 3],
     [5, 7, 0],
     [8, 11, 3],
     [3, 10, 5],
     [0, 9, 5]]
 
# Function call
canMakePaliQueries(str, Q)
 
# This code is contributed by avanitrachhadiya2155
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for the above approach
using System;
class GFG{
 
// Function to find whether String can be
// made palindromic or not for each queries
static void canMakePaliQueries(String str,
                               int [,]Q)
{
    int n = str.Length;
 
    // To store the count of ith character
    // of subString str[0...i]
    int [,]dp = new int[26, n];
 
    for(int i = 0; i < 26; i++)
    {
        
       // Current character
       char currentChar = (char)(i + 'a');
       for(int j = 0; j < n; j++)
       {
        
          // Update [,]dp on the basis
          // recurrence relation
          if (j == 0)
          {
              dp[i,j] = (str[j] ==
                         currentChar) ? 1 : 0;
          }
          else
          {
              dp[i,j] = dp[i, j - 1] +
                         ((str[j] ==
                           currentChar) ? 1 : 0);
          }
       }
    }
 
    // For each queries
    for(int l = 0; l < Q.GetLength(0);l++)
    {
        int []query = GetRow(Q,l);
       int left = query[0];
       int right = query[1];
       int k = query[2];
        
       // To store the count of
       // distinct character
       int unMatchedCount = 0;
       for(int i = 0; i < 26; i++)
       {
            
          // Find occurrence of i + 'a'
          int occurrence = dp[i, right] -
                           dp[i, left] +
                           (str[left] ==
                           (i + 'a') ? 1 : 0);
           
          if (occurrence % 2 == 1)
              unMatchedCount++;
       }
        
       // Half the distinct Count
       int ans = unMatchedCount / 2;
        
       // If half the distinct count is
       // less than equals to K then
       // palindromic String can be made
       if (ans <= k)
       {
           Console.Write("YES\n");
       }
       else
       {
           Console.Write("NO\n");
       }
    }
}
 public static int[] GetRow(int[,] matrix, int row)
  {
    var rowLength = matrix.GetLength(1);
    var rowVector = new int[rowLength];
 
    for (var i = 0; i < rowLength; i++)
      rowVector[i] = matrix[row, i];
 
    return rowVector;
  }
// Driver Code
public static void Main(String[] args)
{
     
    // Given a String str
    String str = "GeeksforGeeks";
 
    // Given Queries
    int [,]Q = { { 1, 5, 3 },
                 { 5, 7, 0 },
                 { 8, 11, 3 },
                 { 3, 10, 5 },
                 { 0, 9, 5 } };
                   
    // Function call
    canMakePaliQueries(str, Q);
}
}
 
// This code is contributed by Princi Singh
chevron_right

Output: 
YES
NO
YES
YES
YES



 

Time Complexity: O(26*N), where N is the length of the string. 
Auxiliary Space: O(26*N), where N is the length of the string. 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




Recommended Posts:


I am currently pursuing B Tech (Hons) in Computer Science I love technology and explore new things I want to become a very good programmer I love to travel and meet new peoples

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Article Tags :