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


Introduction

In this tutorial, we implement an approach to check substring is palindrome by replacing its K characters for Q queries. Palindromes are words that read the same in both directions. When you read a palindromic word from a forward or backward direction, it sounds the same. For example, madam, refer.

Here, Q queries are a numeric array containing the starting index, ending index, and value of K. The starting and ending index values for the input string are used to select only those characters that lie between these starting and ending index values (both values are inclusive).

For the approach, consider a string str, check if its substring can be palindromic by replacing its K characters with Q queries. K is the number of characters replaced to make the substring palindromic.

Example 1

String s = "abcdef"
Queries = {{1, 4, 2}, {0, 4, 2}}

Output

Yes
Yes

Explanation

In the above example, the string is "abcd".

For Query 1 − [1, 4, 1], the starting index is 1, the ending index is 4, and the maximum amount of characters that can be substituted can be a maximum of 2 characters. The substring in the range {1, 4} is "bcde".

By replacing 1 character, it can be a palindromic string, and the palindromic string is "bcdd".

For Query 2 − [0, 4, 3], the starting index is 0, the ending index is 4, and a maximum of 2 characters can be replaced to make the substring a palindrome. The substring lying in the range {0, 4} is "abcde".

Yes, it can be a palindromic string by replacing 2 characters, and that palindromic string is "abcba".

Example 2

String s = "hello"
Queries = { { 1, 4, 0 }, {1, 4, 2 },  { 7, 10, 3 }};

Output

No
Yes
Yes

Explanation

The input string is "helloindia"

For the Query − {1, 4, 0} − The starting index is 1, the ending index is 4 and a maximum of 0 characters can be replaced to make the substring a palindrome. The substring lying in the range {1, 4} is ello.

No, it cannot be a palindromic string by replacing 0 characters.

For the Query − {1, 4, 2} − The starting index is 1, the ending index is 4, and a maximum of 2 characters can be replaced to make the substring a palindrome. The substring lying in the range {1, 4} is 'ello'.

Yes, it can be a palindromic string by replacing 2 characters. The palindromic string after replacing 2 characters is 'elle'.

For the Query − {7, 10, 3} − The starting index is 7, the ending index is 10 and a maximum of 3 characters can be replaced to make the substring a palindrome. The substring lying in the range {6, 9, 2} is 'india'.

Yes, it can be a palindromic string by replacing characters. The palindromic string after replacing 2 characters is 'indni'.

Syntax

  • length() − It is a string class library function defined in the <string> header file. It returns the length of the string. The length of the string is the number of characters of the string.

string_name.length();
  • vector − It is a container in C++ to store elements. It is a dynamic array which is free from the size limit of an array. It is of different data types.

vector<data_type> vector_name;
  • vector<vector<> − It is a vector in vector, a 2 dimensional vector. Its working is similar to a normal vector. Each row is a vector.

vector<vector<data_type> > vector_name;

Algorithm

  • Initialize a string s.

  • Initialize queries using numeric arrays.

  • Use a loop to iterate the string characters.

  • Create a 2d vector that stores the substring which is generated using the starting and ending index values of the query.

  • Process the queries using the substrings and count the unmatched characters.

  • Convert half of the unmatched characters with the remaining characters.

  • The Output is Yes if the number of changed characters is equal to or less than the value of k.

  • If the number of replaced characters is more than the value of K, print No.

  • Process all queries.

Example 1

We implemented one of the demonstrations using dynamic programming in C++. Dynamic programming reduces time complexity and does not execute the same steps multiple times. It divides a task into parts and uses recursion.

#include <bits/stdc++.h>
using namespace std;

//User-defined function to find the palindromic strings from the generated substring 
void findPalindrome(string s, vector<vector<int> >& Q){
   int l = s.length();
   vector<vector<int> > dpa(26, vector<int>(l, 0));  // 2d array to store the character count
   
   //iterating the string to generate the substring 
   for (int x = 0; x < 26; x++)  {
      char currentCharVal= x + 'a';     // value of current character
      for (int y = 0; y < l; y++) {
         // Updating the dp array with new values of counter characters 
         if (y == 0)  {
            dpa[x][y] = (s[y] == currentCharVal); }
         else {
            dpa[x][y] = dpa[x][y - 1] + (s[y] == currentCharVal); 
         }
      }
   }
   
   // Processing queries
   for (auto query : Q) {
      int leftInd = query[0];
      int rightInd = query[1];
      int k = query[2];
      int unMatched = 0;      // Find and storing the unmatched characters
      for (int x = 0; x < 26; x++){
         int cnt = dpa[x][rightInd] - dpa[x][leftInd] + (s[leftInd] == (x + 'a'));
         if (cnt & 1)
            unMatched++;  
      }
      int result = unMatched / 2; // Initializing the value of result variable
      
      // defining the condition for the Output 
      if (result <= k) {cout << "YES\n"; }
      else {cout << "NO\n"; }
   }
}
int main() {
   string s = "helloindia";
   vector<vector<int> > Q;  // Initializing queries
   Q = { { 1, 4, 0 }, {1, 4, 2 }, { 6, 9, 2 }, { 3, 8, 4 }};
   
   // calling the function for processing the queries and generating substring
   findPalindrome(s, Q);
   return 0; 
}

Output

NO
YES
YES
YES

Example 2

We can implement the problem statement in this tutorial without dynamic programming. For generating the substring and processing the queries, loops were used. Count the number of characters that have been changed using the "changes" variable. When the count of changes is less than or equal to K the Output is Yes, otherwise the Output is No.

Used auto to automatically define the variable's data type.

#include <iostream>
#include <vector>
using namespace std;

// Function to generate the substring and process the queries to check substring can be palindrome or not
void checkPalindrome(string s, vector<vector<int>>& Q)  {
   //processing queries
   for (auto query : Q)   {
      int leftVal = query[0];
      int rightVal = query[1];
      int k = query[2];
      int l = rightVal - leftVal + 1;
      int unmatchedCnt = 0;
      //vector to store values of characters
      vector<int> cnt(26, 0);
      //generating substring
      for (int x = leftVal; x <= rightVal; x++)
         cnt[s[x] - 'a']++;
      for (int x = 0; x < 26; x++)  {
         if (cnt[x] % 2 != 0)
            unmatchedCnt++; 
      }
      int changes = unmatchedCnt / 2;
      // condition for the Output
      if (changes <= k) 
         cout << "YES\n";
      else{ 
         cout << "NO\n";  
      }
   }
}

//Code Controller
int main()  {
   string s = "helloindia";
   vector<vector<int>> Q = { { 1, 4, 0 }, {1, 4, 2 }, { 6, 9, 2 }, { 3, 8, 4 }};
   checkPalindrome(s, Q);
   return 0;
}

Output

NO
YES
YES
YES

Conclusion

We have reached the end of this tutorial. In this tutorial, we consider a string and generate substrings through the Queries. We check if the substring can be a palindromic string by replacing the maximum K characters. K is the maximum number of characters replaced for converting a substring to a palindromic string. To implement the task in C++ we used loops and dynamic programming. In this tutorial, we used a 2-dimensional vector for storing queries.

Updated on: 29-Sep-2023

106 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements