Check for Palindrome after every character replacement Query
Last Updated :
14 Apr, 2023
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: "NO"
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 "sesks" which is
palindrome so output "NO"
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 implementation of above idea
C++
#include<bits/stdc++.h>
using namespace std;
bool isPalindrome(string &str)
{
int n = str.size();
for ( int i = 0; i < n/2 ; i++)
if (str[i] != str[n-1-i])
return false ;
return true ;
}
void Query(string &str, int Q,
vector<pair<pair< int , int >, char >> &query)
{
int i1, i2;
char ch;
for ( int q = 0 ; q < Q ; q++ )
{
i1 = query[q].first.first;
i2 = query[q].first.second;
ch = query[q].second;
str[i1] = str[i2] = ch;
(isPalindrome(str)== true ) ? cout << "YES" << endl :
cout << "NO" << endl;
}
}
int main()
{
string str = "geeks" ;
int Q = 2;
vector<pair<pair< int , int >, char >> query
= {{{3, 0}, 'e' }, {{0, 2}, 's' }};
Query(str, Q, query);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static boolean IsPalindrome(String str)
{
int n = str.length();
for ( int i = 0 ; i < n/ 2 ; i++)
if (str.charAt(i) != str.charAt(n- 1 -i))
return false ;
return true ;
}
static void Query(String str, int Q)
{
int i1, i2;
char ch;
Scanner sc = new Scanner(System.in);
for ( int q = 1 ; q <= Q ; q++ )
{
i1 = sc.nextInt();
i2 = sc.nextInt();
ch = sc.next().charAt( 0 );
str = str.substring( 0 ,Math.min(i1,i2)) + ch + str.substring(Math.min(i1+ 1 ,i2+ 1 ), Math.max(i2+ 1 ,i1+ 1 )) + ch +
str.substring(Math.max(i2+ 1 ,i1+ 1 ));
if (IsPalindrome(str)== true )
System.out.println( "YES" );
else
System.out.println( "NO" );
}
sc.close();
}
public static void main(String args[])
{
String str = "geeks" ;
int Q = 2 ;
Query(str, Q);
}
}
|
Python3
def isPalindrome(string: list ) - > bool :
n = len (string)
for i in range (n / / 2 ):
if string[i] ! = string[n - 1 - i]:
return False
return True
def Query(string: list , Q: int ) - > None :
for i in range (Q):
inp = list ( input ().split())
i1 = int (inp[ 0 ])
i2 = int (inp[ 1 ])
ch = inp[ 2 ]
string[i1] = string[i2] = ch
if isPalindrome(string):
print ( "Yes" )
else :
print ( "No" )
if __name__ = = "__main__" :
string = list ( "geeks" )
Q = 2
Query(string, Q)
|
C#
using System;
using System.Collections.Generic;
public class Program
{
public static bool IsPalindrome( ref string str)
{
int n = str.Length;
for ( int i = 0; i < n / 2; i++)
{
if (str[i] != str[n - 1 - i])
{
return false ;
}
}
return true ;
}
public static void Query( ref string str, int Q,
List<Tuple<Tuple< int , int >, char >> query)
{
int i1, i2;
char ch;
for ( int q = 0; q < Q; q++)
{
i1 = query[q].Item1.Item1;
i2 = query[q].Item1.Item2;
ch = query[q].Item2;
str = str.Remove(i1, 1).Insert(i1, ch.ToString());
str = str.Remove(i2, 1).Insert(i2, ch.ToString());
Console.WriteLine(IsPalindrome( ref str) == true ? "YES" : "NO" );
}
}
public static void Main()
{
string str = "geeks" ;
int Q = 2;
List<Tuple<Tuple< int , int >, char >> query =
new List<Tuple<Tuple< int , int >, char >>()
{
Tuple.Create(Tuple.Create(3, 0), 'e' ),
Tuple.Create(Tuple.Create(0, 2), 's' )
};
Query( ref str, Q, query);
}
}
|
Javascript
function isPalindrome(string) {
let n = string.length;
for (let i = 0; i < n / 2; i++) {
if (string[i] !== string[n - 1 - i]) {
return false ;
}
}
return true ;
}
function Query(string, Q) {
for (let i = 0; i < Q; i++) {
let inp = prompt().split( ' ' );
let i1 = parseInt(inp[0]);
let i2 = parseInt(inp[1]);
let ch = inp[2];
string[i1] = string[i2] = ch;
if (isPalindrome(string)) {
console.log( "Yes" );
} else {
console.log( "No" );
}
}
}
let string = [ 'g' , 'e' , 'e' , 'k' , 's' ];
let Q = 2;
Query(string, Q);
|
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
CPP
#include <bits/stdc++.h>
using namespace std;
void addRemoveUnequal(string& str, int index, int n,
unordered_set< int >& S)
{
if (str[index] == str[n - 1 - index]) {
auto it = S.find(index);
if (it != S.end())
S.erase(it);
}
else
S.insert(index);
}
void Query(string& str, int Q,
vector<pair<pair< int , int >, char >> &query)
{
int n = str.length();
unordered_set< int > S;
for ( int i = 0; i < n / 2; i++)
if (str[i] != str[n - 1 - i])
S.insert(i);
for ( int q = 0; q < Q; q++) {
int i1, i2;
char ch;
i1 = query[q].first.first;
i2 = query[q].first.second;
ch = query[q].second;
str[i1] = str[i2] = ch;
if (i1 > n / 2)
i1 = n - 1 - i1;
if (i2 > n / 2)
i2 = n - 1 - i2;
addRemoveUnequal(str, i1, n, S);
addRemoveUnequal(str, i2, n, S);
S.empty() ? cout << "YES\n" : cout << "NO\n" ;
}
}
int main()
{
string str = "geeks" ;
int Q = 2;
vector<pair<pair< int , int >, char > > query
= { { { 3, 0 }, 'e' }, { { 0, 2 }, 's' } };
Query(str, Q, query);
return 0;
}
|
Java
import java.util.*;
class Main {
static void addRemoveUnequal(StringBuilder str, int index, int n, HashSet<Integer> S) {
if (str.charAt(index) == str.charAt(n - 1 - index)) {
if (S.contains(index))
S.remove(index);
}
else {
S.add(index);
}
}
static void Query(StringBuilder str, int Q, ArrayList<Pair<Pair<Integer, Integer>, Character>> query) {
int n = str.length();
HashSet<Integer> S = new HashSet<>();
for ( int i = 0 ; i < n / 2 ; i++)
if (str.charAt(i) != str.charAt(n - 1 - i))
S.add(i);
for ( int q = 0 ; q < Q; q++) {
int i1, i2;
char ch;
i1 = query.get(q).first.first;
i2 = query.get(q).first.second;
ch = query.get(q).second;
str.setCharAt(i1, ch);
str.setCharAt(i2, ch);
if (i1 > n / 2 )
i1 = n - 1 - i1;
if (i2 > n / 2 )
i2 = n - 1 - i2;
addRemoveUnequal(str, i1, n, S);
addRemoveUnequal(str, i2, n, S);
System.out.println(S.isEmpty() ? "YES" : "NO" );
}
}
public static void main(String[] args) {
StringBuilder str = new StringBuilder( "geeks" );
int Q = 2 ;
ArrayList<Pair<Pair<Integer, Integer>, Character>> query = new ArrayList<>();
query.add( new Pair<>( new Pair<>( 3 , 0 ), 'e' ));
query.add( new Pair<>( new Pair<>( 0 , 2 ), 's' ));
Query(str, Q, query);
}
}
class Pair<U, V> {
public final U first;
public final V second;
public Pair(U first, V second) {
this .first = first;
this .second = second;
}
}
|
Python3
def addRemoveUnequal(s, index, n, S):
if s[index] = = s[n - 1 - index]:
if index in S:
S.remove(index)
else :
S.add(index)
def Query(s, Q, query):
n = len (s)
S = set ()
for i in range (n / / 2 ):
if s[i] ! = s[n - 1 - i]:
S.add(i)
for q in range (Q):
i1, i2 = query[q][ 0 ]
ch = query[q][ 1 ]
s = s[:i1] + ch + s[i1 + 1 :]
s = s[:i2] + ch + s[i2 + 1 :]
if i1 > n / / 2 :
i1 = n - 1 - i1
if i2 > n / / 2 :
i2 = n - 1 - i2
addRemoveUnequal(s, i1, n, S)
addRemoveUnequal(s, i2, n, S)
print ( "NO" if S else "YES" )
if __name__ = = '__main__' :
s = "geeks"
Q = 2
query = [(( 3 , 0 ), 'e' ), (( 0 , 2 ), 's' )]
Query(s, Q, query)
|
C#
using System;
using System.Collections.Generic;
using System.Text;
class Program
{
static void AddRemoveUnequal(StringBuilder str, int index, int n, HashSet< int > S)
{
if (str[index] == str[n - 1 - index])
{
if (S.Contains(index))
{
S.Remove(index);
}
}
else
{
S.Add(index);
}
}
static void Query(StringBuilder str, int Q, List<Tuple<Tuple< int , int >, char >> query)
{
int n = str.Length;
HashSet< int > S = new HashSet< int >();
for ( int i = 0; i < n / 2; i++)
{
if (str[i] != str[n - 1 - i])
{
S.Add(i);
}
}
for ( int q = 0; q < Q; q++)
{
int i1, i2;
char ch;
i1 = query[q].Item1.Item1;
i2 = query[q].Item1.Item2;
ch = query[q].Item2;
str[i1] = ch;
str[i2] = ch;
if (i1 > n / 2)
{
i1 = n - 1 - i1;
}
if (i2 > n / 2)
{
i2 = n - 1 - i2;
}
AddRemoveUnequal(str, i1, n, S);
AddRemoveUnequal(str, i2, n, S);
Console.WriteLine(S.Count == 0 ? "YES" : "NO" );
}
}
static void Main( string [] args)
{
StringBuilder str = new StringBuilder( "geeks" );
int Q = 2;
List<Tuple<Tuple< int , int >, char >> query = new List<Tuple<Tuple< int , int >, char >>();
query.Add( new Tuple<Tuple< int , int >, char >( new Tuple< int , int >(3, 0), 'e' ));
query.Add( new Tuple<Tuple< int , int >, char >( new Tuple< int , int >(0, 2), 's' ));
Query(str, Q, query);
}
}
|
Javascript
function addRemoveUnequal(s, index, n, S)
{
if (s[index] === s[n - 1 - index])
{
if (S.has(index)) {
S. delete (index);
}
}
else {
S.add(index);
}
}
function Query(s, Q, query) {
let n = s.length;
let S = new Set();
for (let i = 0; i < n / 2; i++) {
if (s[i] !== s[n - 1 - i]) {
S.add(i);
}
}
for (let q = 0; q < Q; q++) {
let [i1, i2] = query[q][0];
let ch = query[q][1];
s = s.substring(0, i1) + ch + s.substring(i1 + 1);
s = s.substring(0, i2) + ch + s.substring(i2 + 1);
if (i1 > n / 2) {
i1 = n - 1 - i1;
}
if (i2 > n / 2) {
i2 = n - 1 - i2;
}
addRemoveUnequal(s, i1, n, S);
addRemoveUnequal(s, i2, n, S);
console.log(S.size === 0 ? "YES" : "NO" );
}
}
let s = "geeks" ;
let Q = 2;
let query = [[[3, 0], 'e' ], [[0, 2], 's' ]];
Query(s, Q, query);
|
Time Complexity: O(Q + n) under the assumption that set insert, delete and find operations take O(1) time.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...