Open In App

Queries to check if substring[L…R] is palindrome or not

Last Updated : 10 Aug, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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
?>


Output

No
Yes



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:
 

  1. Define a function named isPalindrome which takes a string ‘s’, and two integers ‘l’ and ‘r’ as arguments.
  2. Inside the function, use a while loop to iterate from both ends of the substring, starting from l and r indices respectively.
  3. Check if the characters at both ends are equal. If they are not equal, return false.
  4. If we reach the middle of the substring, it means the substring is a palindrome, so return true.
  5. In the main function, initialize a string ‘s’ and an integer 2D array ‘queries’ which contains the indices of the substrings to be checked.
  6. Get the number of queries ‘q’ by dividing the size of the queries array by the size of a single query array.
  7. Iterate through the queries using a for loop and call the isPalindrome function for each query.
  8. If the isPalindrome function returns true, print “Yes”, else print “No”.
  9. 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).



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads