Queries to check if substring[L...R] is palindrome or not
Last Updated :
10 Aug, 2023
Given a string str and Q queries. Every query consists of two numbers L and R. The task is to print if the sub-string[L...R] is palindrome or not.
Examples:
Input: str = "abacccde", Q[][] = {{0, 2}, {1, 2}, {2, 4}, {3, 5}}
Output:
Yes
No
No
Yes
Input: str = "abaaab", Q[][] = {{0, 1}, {1, 5}}
Output:
No
Yes
Simple Approach: A naive approach is to check for every sub-string if it is palindrome or not. In the worst case, every query can take up to O(Q).
Efficient Approach: An efficient approach is to use Dynamic Programming to solve the above problem. We can initially create the DP table which stores if substring[i....j] is palindrome or not. We maintain a boolean dp[n][n] that is filled in a bottom-up manner. The value of dp[i][j] is true if the substring is a palindrome, otherwise false. To calculate dp[i][j], we first check the value of dp[i+1][j-1], if the value is true and s[i] is the same as s[j], then we make dp[i][j] true. Otherwise, the value of dp[i][j] is made false.
Now, for every query, check if dp[l][r] is true or not.
Below is the implementation of the above approach:
C++
// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
#define N 100
// Pre-processing function
void pre_process(bool dp[N][N], string s)
{
// Get the size of the string
int n = s.size();
// Initially mark every
// position as false
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
dp[i][j] = false;
}
// For the length
for (int j = 1; j <= n; j++) {
// Iterate for every index with
// length j
for (int i = 0; i <= n - j; i++) {
// If the length is less than 2
if (j <= 2) {
// If characters are equal
if (s[i] == s[i + j - 1])
dp[i][i + j - 1] = true;
}
// Check for equal
else if (s[i] == s[i + j - 1])
dp[i][i + j - 1] = dp[i + 1][i + j - 2];
}
}
}
// Function to answer every query in O(1)
void answerQuery(int l, int r, bool dp[N][N])
{
if (dp[l][r])
cout << "Yes\n";
else
cout << "No\n";
}
// Driver code
int main()
{
string s = "abaaab";
bool dp[N][N];
pre_process(dp, s);
int queries[][2] = { { 0, 1 }, { 1, 5 } };
int q = sizeof(queries) / sizeof(queries[0]);
for (int i = 0; i < q; i++)
answerQuery(queries[i][0], queries[i][1], dp);
return 0;
}
Java
// Java implementation of the approach
class GFG {
static int N = 100;
// Pre-processing function
static void pre_process(boolean dp[][], char[] s)
{
// Get the size of the string
int n = s.length;
// Initially mark every
// position as false
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
dp[i][j] = false;
}
}
// For the length
for (int j = 1; j <= n; j++) {
// Iterate for every index with
// length j
for (int i = 0; i <= n - j; i++) {
// If the length is less than 2
if (j <= 2) {
// If characters are equal
if (s[i] == s[i + j - 1]) {
dp[i][i + j - 1] = true;
}
}
// Check for equal
else if (s[i] == s[i + j - 1]) {
dp[i][i + j - 1] = dp[i + 1][i + j - 2];
}
}
}
}
// Function to answer every query in O(1)
static void answerQuery(int l, int r, boolean dp[][])
{
if (dp[l][r]) {
System.out.println("Yes");
}
else {
System.out.println("No");
}
}
// Driver code
public static void main(String[] args)
{
String s = "abaaab";
boolean[][] dp = new boolean[N][N];
pre_process(dp, s.toCharArray());
int queries[][] = { { 0, 1 }, { 1, 5 } };
int q = queries.length;
for (int i = 0; i < q; i++) {
answerQuery(queries[i][0], queries[i][1], dp);
}
}
}
// This code contributed by Rajput-Ji
Python3
# Python3 implementation of the approach
N = 100
# Pre-processing function
def pre_process(dp, s):
# Get the size of the string
n = len(s)
# Initially mark every
# position as false
for i in range(n):
for j in range(n):
dp[i][j] = False
# For the length
for j in range(1, n + 1):
# Iterate for every index with
# length j
for i in range(n - j + 1):
# If the length is less than 2
if (j <= 2):
# If characters are equal
if (s[i] == s[i + j - 1]):
dp[i][i + j - 1] = True
# Check for equal
elif (s[i] == s[i + j - 1]):
dp[i][i + j - 1] = dp[i + 1][i + j - 2]
# Function to answer every query in O(1)
def answerQuery(l, r, dp):
if (dp[l][r]):
print("Yes")
else:
print("No")
# Driver code
s = "abaaab"
dp = [[0 for i in range(N)]
for i in range(N)]
pre_process(dp, s)
queries = [[0, 1], [1, 5]]
q = len(queries)
for i in range(q):
answerQuery(queries[i][0],
queries[i][1], dp)
# This code is contributed by mohit kumar
C#
// C# implementation of the approach
using System;
class GFG {
static int N = 100;
// Pre-processing function
static void pre_process(bool[, ] dp, char[] s)
{
// Get the size of the string
int n = s.Length;
// Initially mark every
// position as false
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
dp[i, j] = false;
}
}
// For the length
for (int j = 1; j <= n; j++) {
// Iterate for every index with
// length j
for (int i = 0; i <= n - j; i++) {
// If the length is less than 2
if (j <= 2) {
// If characters are equal
if (s[i] == s[i + j - 1]) {
dp[i, i + j - 1] = true;
}
}
// Check for equal
else if (s[i] == s[i + j - 1]) {
dp[i, i + j - 1] = dp[i + 1, i + j - 2];
}
}
}
}
// Function to answer every query in O(1)
static void answerQuery(int l, int r, bool[, ] dp)
{
if (dp[l, r]) {
Console.WriteLine("Yes");
}
else {
Console.WriteLine("No");
}
}
// Driver code
public static void Main()
{
string s = "abaaab";
bool[, ] dp = new bool[N, N];
pre_process(dp, s.ToCharArray());
int[, ] queries = { { 0, 1 }, { 1, 5 } };
int q = queries.Length;
for (int i = 0; i < q; i++) {
answerQuery(queries[i, 0], queries[i, 1], dp);
}
}
}
// This code is contributed by Ankit.
JavaScript
<script>
// javascript implementation of the approach
var N = 100;
// Pre-processing function
function pre_process( dp, s) {
// Get the size of the string
var n = s.length;
// Initially mark every
// position as false
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
dp[i][j] = false;
}
}
// For the length
for (j = 1; j <= n; j++) {
// Iterate for every index with
// length j
for (i = 0; i <= n - j; i++) {
// If the length is less than 2
if (j <= 2) {
// If characters are equal
if (s[i] == s[i + j - 1]) {
dp[i][i + j - 1] = true;
}
}
// Check for equal
else if (s[i] == s[i + j - 1]) {
dp[i][i + j - 1] = dp[i + 1][i + j - 2];
}
}
}
}
// Function to answer every query in O(1)
function answerQuery(l , r, dp) {
if (dp[l][r]) {
document.write("Yes<br/>");
}
else {
document.write("No<br/>");
}
}
// Driver code
var s = "abaaab";
var dp = Array(N).fill().map(()=>Array(N).fill());
pre_process(dp, s);
var queries = [ [ 0, 1 ], [ 1, 5 ] ];
var q = queries.length;
for (i = 0; i < q; i++) {
answerQuery(queries[i][0], queries[i][1], dp);
}
// This code contributed by Rajput-Ji
</script>
PHP
<?php
// PHP implementation of the approach
$N = 100;
// Pre-processing function
function pre_process($dp, $s)
{
// Get the size of the string
$n = strlen($s);
// Initially mark every
// position as false
for ($i = 0; $i < $n; $i++)
{
for ($j = 0; $j < $n; $j++)
$dp[$i][$j] = false;
}
// For the length
for ($j = 1; $j <= $n; $j++)
{
// Iterate for every index with
// length j
for ($i = 0; $i <= $n - $j; $i++)
{
// If the length is less than 2
if ($j <= 2)
{
// If characters are equal
if ($s[$i] == $s[$i + $j - 1])
$dp[$i][$i + $j - 1] = true;
}
// Check for equal
else if ($s[$i] == $s[$i + $j - 1])
$dp[$i][$i + $j - 1] = $dp[$i + 1][$i + $j - 2];
}
}
return $dp;
}
// Function to answer every query in O(1)
function answerQuery($l, $r, $dp)
{
if ($dp[$l][$r])
echo "Yes\n";
else
echo "No\n";
}
// Driver code
$s = "abaaab";
$dp = array(array());
$dp = pre_process($dp, $s);
$queries = array(array(0, 1),
array(1, 5));
$q = count($queries);
for ($i = 0; $i < $q; $i++)
answerQuery($queries[$i][0],
$queries[$i][1], $dp);
// This code is contributed by Ryuga
?>
Time Complexity: O(N*N), as we are using nested loops for traversing N*N times. Where N is the length of the string.
Auxiliary Space: O(N*N), as we are using extra space for the dp matrix.
New Approach:- Another approach to check if a substring is a palindrome or not is to use the two-pointer technique. We can iterate from both ends of the substring and check if the characters at both ends are equal. If they are equal, we move the left pointer one step to the right and the right pointer one step to the left. If they are not equal, we can conclude that the substring is not a palindrome.
Algorithm:
- Define a function named isPalindrome which takes a string 's', and two integers 'l' and 'r' as arguments.
- Inside the function, use a while loop to iterate from both ends of the substring, starting from l and r indices respectively.
- Check if the characters at both ends are equal. If they are not equal, return false.
- If we reach the middle of the substring, it means the substring is a palindrome, so return true.
- In the main function, initialize a string 's' and an integer 2D array 'queries' which contains the indices of the substrings to be checked.
- Get the number of queries 'q' by dividing the size of the queries array by the size of a single query array.
- Iterate through the queries using a for loop and call the isPalindrome function for each query.
- If the isPalindrome function returns true, print "Yes", else print "No".
- The program ends after all the queries have been answered.
Here is the implementation of the two-pointer approach:
C++
#include <iostream>
using namespace std;
bool isPalindrome(string s, int l, int r) {
while (l < r) {
if (s[l] != s[r])
return false;
l++;
r--;
}
return true;
}
int main() {
string s = "abaaab";
int queries[][2] = { { 0, 1 }, { 1, 5 } };
int q = sizeof(queries) / sizeof(queries[0]);
for (int i = 0; i < q; i++) {
int l = queries[i][0], r = queries[i][1];
if (isPalindrome(s, l, r))
cout << "Yes\n";
else
cout << "No\n";
}
return 0;
}
Java
public class Main {
public static boolean isPalindrome(String s, int l, int r) {
while (l < r) {
if (s.charAt(l) != s.charAt(r))
return false;
l++;
r--;
}
return true;
}
public static void main(String[] args) {
String s = "abaaab";
int[][] queries = { { 0, 1 }, { 1, 5 } };
int q = queries.length;
for (int i = 0; i < q; i++) {
int l = queries[i][0], r = queries[i][1];
if (isPalindrome(s, l, r))
System.out.println("Yes");
else
System.out.println("No");
}
}
}
Python
def is_palindrome(s, l, r):
while l < r:
if s[l] != s[r]:
return False
l += 1
r -= 1
return True
s = "abaaab"
queries = [[0, 1], [1, 5]]
q = len(queries)
for i in range(q):
l, r = queries[i]
if is_palindrome(s, l, r):
print("Yes")
else:
print("No")
C#
// C# program to check if a substring is a palindrome
using System;
class GFG
{
// Function to check if a substring is a palindrome
static bool IsPalindrome(string s, int l, int r)
{
while (l < r)
{
if (s[l] != s[r])
return false;
l++;
r--;
}
return true;
}
// Driver Code
static void Main()
{
string s = "abaaab";
int[,] queries = { { 0, 1 }, { 1, 5 } };
int q = queries.GetLength(0);
// Iterate over each query
for (int i = 0; i < q; i++)
{
int l = queries[i, 0];
int r = queries[i, 1];
if (IsPalindrome(s, l, r))
Console.WriteLine("Yes");
else
Console.WriteLine("No");
}
}
}
JavaScript
// Function to check if a substring is a palindrome
function isPalindrome(s, l, r) {
while (l < r) {
if (s[l] !== s[r]) {
return false;
}
l++;
r--;
}
return true;
}
// Driver Code
const s = "abaaab";
const queries = [[0, 1], [1, 5]];
const q = queries.length;
// Iterate over each query
for (let i = 0; i < q; i++) {
const l = queries[i][0];
const r = queries[i][1];
if (isPalindrome(s, l, r)) {
console.log("Yes");
} else {
console.log("No");
}
}
Output:-
No
Yes
Time complexity:
- The function `isPalindrome()` takes O((r-l)/2) time to check if a substring is a palindrome or not.
- The for loop in the `main()` function runs q times and each iteration calls `isPalindrome()` function once.
- Therefore, the time complexity of the overall program is O(q*(r-l)/2) or simply O(q*r).
Auxiliary Space:
- The space used by the program is constant, independent of the size of the input string.
- Therefore, the auxiliary space complexity of the program is O(1).
Similar Reads
Queries on substring palindrome formation
Given a string S, and two types of queries. Type 1: 1 L x, Indicates update Lth index of string S by x character. Type 2: 2 L R, Find if characters between position L and R of string, S can form a palindrome string. If palindrome can be formed print "Yes", else print "No". 1 <= L, R <= |S| Exa
15+ min read
Check given string is oddly palindrome or not
Given string str, the task is to check if characters at the odd indexes of str form a palindrome string or not. If not then print "No" else print "Yes".Examples: Input: str = "osafdfgsg", N = 9 Output: Yes Explanation: Odd indexed characters are = { s, f, f, s } so it will make palindromic string, "
6 min read
Find if string is K-Palindrome or not | Set 2
Given a string, find out if the string is K-Palindrome or not. A K-palindrome string transforms into a palindrome on removing at most k characters from it.Examples: Input : String - abcdecba, k = 1 Output : Yes String can become palindrome by removing 1 character i.e. either d or e Input : String -
8 min read
Check given string is oddly palindrome or not | Set 2
Given string str, the task is to check if characters at the odd indexes of str form a palindrome string or not. If not then print "No" else print "Yes". Examples: Input: str = "osafdfgsg", N = 9 Output: Yes Explanation: Odd indexed characters are = { s, f, f, s } so it will make palindromic string,
11 min read
Find if string is K-Palindrome or not | Set 1
Given a string S, find out if the string is K-Palindrome or not. A K-palindrome string transforms into a palindrome on removing at most K characters from it.Examples : Input: S = "abcdecba", k = 1Output: YesExplanation: String can become palindrome by removing 1 character i.e. either d or e. Input:
15+ min read
Check if sum of any subarray is Palindrome or not
Given an array arr[] of size N. the task is to check whether there exists any subarray of size atleast 2 such that its sum is palindrome. If such a subarray exists, then print YES. Otherwise, print NO.Examples: Input: arr[] = {10, 6, 7, 9, 12} Output: Yes Explanation: The subarray [6, 7, 9] with sum
8 min read
Recursive function to check if a string is palindrome
Given a string s, the task is to check if it is a palindrome or not.Examples:Input: s = "abba"Output: YesExplanation: s is a palindromeInput: s = "abc" Output: NoExplanation: s is not a palindromeUsing Recursion and Two Pointers - O(n) time and O(n) spaceThe idea is to recursively check if the strin
8 min read
Check if string can be rearranged so that every Odd length Substring is Palindrome
Given a string S. The task is to check whether it is possible to rearrange the string such that every substring of odd length is a palindrome. Examples: Input: S = "oiooi" Output: YES The string can be rearranged as "oioio" Input: S = "yuyuo" Output: NO Approach: The very first observation is if all
7 min read
Palindrome Substring Queries
Given a string str of length n and a 2d array queries[][], where each query queries[i] is of type [i, j]. For each query, your task is to check if the substring str[i:j] is a palindrome.Examples : Input: str = "abaaabaaaba"queries[][] = [ [0, 10], [5, 8], [2, 5], [5, 9] ]Output: 1 0 0 1Explanation:
15+ min read
Program to check if an Array is Palindrome or not
Given an array, the task is to determine whether an array is a palindrome or not.Examples: Input: arr[] = {3, 6, 0, 6, 3} Output: Palindrome Input: arr[] = {1, 2, 3, 4, 5} Output: Not Palindrome Approach: Initialise flag to unset int flag = 0.Loop the array till size n/2In a loop check if arr[i]! =
5 min read