Given a string str and Q queries. Each query contains a pair of integers (i1, i2) and a character ‘ch’. We need to replace characters at indexes i1 and i2 with new character ‘ch’ and then tell if string str is palindrome or not. (0 <= i1, i2 < string_length) Examples:
Input : str = “geeks” Q = 2 query 1: i1 = 3 ,i2 = 0, ch = ‘e’ query 2: i1 = 0 ,i2 = 2 , ch = ‘s’ Output : query 1: “NO” query 2: “YES” Explanation : In query 1 : i1 = 3 , i2 = 0 ch = ‘e’ After replacing char at index i1, i2 str[3] = ‘e’, str[0] = ‘e’ string become “eeees” which is not palindrome so output “NO” In query 2 : i1 = 0 i2 = 2 ch = ‘s’ After replacing char at index i1 , i2 str[0] = ‘s’, str[2] = ‘s’ string become “seses” which is palindrome so output “YES” Input : str = “jasonamat” Q = 3 query 1: i1 = 3, i2 = 8 ch = ‘j’ query 2: i1 = 2, i2 = 6 ch = ‘n’ query 3: i1 = 3, i2 = 7 ch = ‘a’ Output : query 1: “NO” query 2: “NO” query 3: “YES”
A Simple solution is that for each query , we replace character at indexes (i1 & i2) with a new character ‘ch’ and then check if string is palindrome or not.
Below is C++ implementation of above idea
// C++ program to find if string becomes palindrome // after every query. #include<bits/stdc++.h> using namespace std; // Function to check if string is Palindrome or Not bool IsPalindrome(string &str) { int n = strlen (str); for ( int i = 0; i < n/2 ; i++) if (str[i] != str[n-1-i]) return false ; return true ; } // Takes two inputs for Q queries. For every query, it // prints Yes if string becomes palindrome and No if not. void Query(string &str, int Q) { int i1, i2; char ch; // Process all queries one by one for ( int q = 1 ; q <= Q ; q++ ) { cin >> i1 >> i2 >> ch; // query 1: i1 = 3 ,i2 = 0, ch = 'e' // query 2: i1 = 0 ,i2 = 2 , ch = 's' // replace character at index i1 & i2 with new 'ch' str[i1] = str[i2] = ch; // check string is palindrome or not (isPalindrome(str)== true ) ? cout << "YES" << endl : cout << "NO" << endl; } } // Driver program int main() { char str[] = "geeks" ; int Q = 2; Query(str, Q); return 0; } |
Input:
3 0 e 0 2 s
Output:
"NO" "YES"
Time complexity O(Q*n) (n is length of string )
An efficient solution is to use hashing. We create an empty hash set that stores indexes that are unequal in palindrome (Note: ” we have to store indexes only first half of string that are unequal “).
Given string "str" and length 'n'. Create an empty set S and store unequal indexes in first half. Do following for each query : 1. First replace character at indexes i1 & i2 with new char "ch" 2. If i1 and/or i2 are/is greater than n/2 then convert into first half index(es) 3. In this step we make sure that S contains maintains unequal indexes of first half. a) If str[i1] == str [n - 1 - i1] means i1 becomes equal after replacement, remove it from S (if present) Else add i1 to S b) Repeat step a) for i2 (replace i1 with i2) 4. If S is empty then string is palindrome else NOT
Below is C++ implementation of above idea
// C++/c program check if given string is palindrome // or not after every query #include<bits/stdc++.h> using namespace std; // This function makes sure that set S contains // unequal characters from first half. This is called // for every character. void addRemoveUnequal(string &str, int index, int n, unordered_set< int > &S) { // If character becomes equal after query if (str[index] == str[n-1-index]) { // Remove the current index from set if it // is present auto it = S.find(index); if (it != S.end()) S.erase(it) ; } // If not equal after query, insert it into set else S.insert(index); } // Takes two inputs for Q queries. For every query, it // prints Yes if string becomes palindrome and No if not. void Query(string &str, int Q) { int n = str.length(); // create an empty set that store indexes of // unequal location in palindrome unordered_set< int > S; // we store indexes that are unequal in palindrome // traverse only first half of string for ( int i=0; i<n/2; i++) if (str[i] != str[n-1-i]) S.insert(i); // traversal the query for ( int q=1; q<=Q; q++) { // query 1: i1 = 3, i2 = 0, ch = 'e' // query 2: i1 = 0, i2 = 2, ch = 's' int i1, i2; char ch; cin >> i1 >> i2 >> ch; // Replace characters at indexes i1 & i2 with // new char 'ch' str[i1] = str [i2] = ch; // If i1 and/or i2 greater than n/2 // then convert into first half index if (i1 > n/2) i1 = n- 1 -i1; if (i2 > n/2) i2 = n -1 - i2; // call addRemoveUnequal function to insert and remove // unequal indexes addRemoveUnequal(str, i1 , n, S ); addRemoveUnequal(str, i2 , n, S ); // if set is not empty then string is not palindrome S.empty()? cout << "YES
" : cout << "NO
" ; } } // Driver program int main() { string str = "geeks" ; int Q = 2 ; Query(str, Q); return 0; } |
Input:
3 0 e 0 2 s
Output:
"NO" "YES"
Time Complexity : O(Q + n) under the assumption that set insert, delete and find operations take O(1) time.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
leave a comment
0 Comments