Palindrome Substring Queries
Last Updated :
27 Apr, 2025
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 1
Explanation: Lets process all the queries one by one:
a. [0, 10]: The substring is “abaaabaaaba” which is a palindrome.
b. [5, 8]: The substring is “baaa” which is not a palindrome.
c. [2, 5]: The substring is “aaab” which is not a palindrome.
d. [5, 9]: The substring is “baaab” which is a palindrome.
Input: str = “abdcaaa”
queries[][] = [ [0, 1], [2, 2], [4, 6] ]
Output: 0 1 1
Explanation: Lets process all the queries one by one:
a. [0, 1]: The substring is “ab” which is not a palindrome.
b. [2, 2]: The substring is “baaa” which is not a palindrome.
c. [4, 6]: The substring is “aaa” which is a palindrome.
[Naive Approach] – O(n * q) Time and O(1) Space
The idea is to process each query one-by-one and for each query [i, j] use for loop to check if the substring str[i…j] is palindrome.
C++
#include <bits/stdc++.h>
using namespace std;
// function to check if a substring is a palindrome
bool isPalindrome(string str, int start, int end) {
while (start < end) {
if (str[start] != str[end]) {
return false;
}
start++;
end--;
}
return true;
}
// function to check if the substring
// is a palindrome for each query
vector<int> palindromeQueries(string str,
vector<vector<int>>& queries) {
// to store the results
vector<int> result;
for (auto query : queries) {
int start = query[0];
int end = query[1];
// check if the substring is a palindrome
if (isPalindrome(str, start, end)) {
result.push_back(1);
} else {
result.push_back(0);
}
}
return result;
}
int main() {
string str = "abaaabaaaba";
vector<vector<int>> queries =
{{0, 10}, {5, 8}, {2, 5}, {5, 9}};
vector<int> res =
palindromeQueries(str, queries);
for(auto i: res) {
cout << i << " ";
}
return 0;
}
Java
import java.util.*;
public class GfG {
// function to check if a substring is a palindrome
static boolean isPalindrome(String str, int start, int end) {
while (start < end) {
if (str.charAt(start) != str.charAt(end)) {
return false;
}
start++;
end--;
}
return true;
}
// function to check if the substring
// is a palindrome for each query
static List<Integer> palindromeQueries(String str, List<int[]> queries) {
// to store the results
List<Integer> result = new ArrayList<>();
for (int[] query : queries) {
int start = query[0];
int end = query[1];
// check if the substring is a palindrome
if (isPalindrome(str, start, end)) {
result.add(1);
} else {
result.add(0);
}
}
return result;
}
public static void main(String[] args) {
String str = "abaaabaaaba";
List<int[]> queries = Arrays.asList(
new int[]{0, 10}, new int[]{5, 8},
new int[]{2, 5}, new int[]{5, 9}
);
List<Integer> res = palindromeQueries(str, queries);
for (int i : res) {
System.out.print(i + " ");
}
}
}
Python
# function to check if a substring is a palindrome
def isPalindrome(string, start, end):
while start < end:
if string[start] != string[end]:
return False
start += 1
end -= 1
return True
# function to check if the substring
# is a palindrome for each query
def palindromeQueries(string, queries):
# to store the results
result = []
for query in queries:
start = query[0]
end = query[1]
# check if the substring is a palindrome
if isPalindrome(string, start, end):
result.append(1)
else:
result.append(0)
return result
if __name__ == "__main__":
string = "abaaabaaaba"
queries = [[0, 10], [5, 8], [2, 5], [5, 9]]
res = palindromeQueries(string, queries)
print(" ".join(map(str, res)))
C#
using System;
using System.Collections.Generic;
public class GfG {
// function to check if a substring is a palindrome
static bool IsPalindrome(string str, int start, int end) {
while (start < end) {
if (str[start] != str[end]) {
return false;
}
start++;
end--;
}
return true;
}
// function to check if the substring
// is a palindrome for each query
static List<int> PalindromeQueries(string str, List<int[]> queries) {
// to store the results
List<int> result = new List<int>();
foreach (var query in queries) {
int start = query[0];
int end = query[1];
// check if the substring is a palindrome
if (IsPalindrome(str, start, end)) {
result.Add(1);
} else {
result.Add(0);
}
}
return result;
}
public static void Main(string[] args) {
string str = "abaaabaaaba";
List<int[]> queries = new List<int[]> {
new int[] {0, 10}, new int[] {5, 8},
new int[] {2, 5}, new int[] {5, 9}
};
List<int> res = PalindromeQueries(str, queries);
Console.WriteLine(string.Join(" ", res));
}
}
JavaScript
// function to check if a substring is a palindrome
function isPalindrome(str, start, end) {
while (start < end) {
if (str[start] !== str[end]) {
return false;
}
start++;
end--;
}
return true;
}
// function to check if the substring
// is a palindrome for each query
function palindromeQueries(str, queries) {
// to store the results
let result = [];
for (let query of queries) {
let start = query[0];
let end = query[1];
// check if the substring is a palindrome
if (isPalindrome(str, start, end)) {
result.push(1);
} else {
result.push(0);
}
}
return result;
}
function main() {
let str = "abaaabaaaba";
let queries = [[0, 10], [5, 8], [2, 5], [5, 9]];
let res = palindromeQueries(str, queries);
console.log(res.join(" "));
}
main();
[Expected Approach] – Using Cumulative Hash – O(n + q) Time and O(n) Space
The idea is similar to Rabin Karp string matching. We use string hashing. What we do is that we calculate cumulative hash values of the string in the original string as well as the reversed string in two arrays- prefix[] and suffix[].
How to calculate the cumulative hash values?
Suppose our string is str[], then the cumulative hash function to fill our prefix[] array used is-
prefix[0] = 0
prefix[i] = str[0] + str[1] * 101 + str[2] * 1012 + …… + str[i-1] * 101i-1
For example, take the string- “abaaabxyaba”
prefix[0] = 0
prefix[1] = 97 (ASCII Value of ‘a’ is 97)
prefix[2] = 97 + 98 * 101
prefix[3] = 97 + 98 * 101 + 97 * 1012
………………………
………………………
prefix[11] = 97 + 98 * 101 + 97 * 1012 + ……..+ 97 * 10110
Now the reason to store in that way is that we can easily find the hash value of any substring in O(1) time using
hash(L, R) = prefix[R+1] – prefix[L]
For example, hash (1, 5) = hash (“baaab”) = prefix[6] – prefix[1] = 98 * 101 + 97 * 1012 + 97 * 1013 + 97 * 1014 + 98 * 1015 = 1040184646587 [. We will use this weird value later to explain what’s happening].
Similar to this we will fill our suffix[] array as-
suffix[0] = 0
suffix[i] = str[n-1] + str[n-2] * 1011 + str[n-3] * 1012 + …… + str[n-i] * 101i-1
For example, take the string- “abaaabxyaba”
suffix[0] = 0
suffix[1] = 97 (ASCII Value of ‘a’ is 97)
suffix[2] = 97 + 98 * 101
suffix[3] = 97 + 98 * 101 + 97 * 1012
………………………
………………………
suffix[11] = 97 + 98 * 101 + 97 * 1012 + ……..+ 97 * 10110
Now the reason to store in that way is that we can easily find the reverse hash value of any substring in O(1) time using
reverse_hash(L, R) = hash (R, L) = suffix[n-L] – suffix[n-R-1]
where n = length of string
For “abaaabxyaba”, n = 11
reverse_hash(1, 5) = reverse_hash(“baaab”) = hash(“baaab”) [Reversing “baaab” gives “baaab”]
hash(“baaab”) = suffix[11-1] – suffix[11-5-1] = suffix[10] – suffix[5] = 98 * 1015 + 97 * 1016 + 97 * 1017 + 97 * 1018 + 98 * 1019 = 108242031437886501387
Now there doesn’t seem to be any relationship between these two weird integers – 1040184646587 and 108242031437886501387
Think again. Is there any relation between these two massive integers ?
Yes, there is and this observation is the core of this program/article.
1040184646587 * 1014 = 108242031437886501387
Try thinking about this and you will find that any substring starting at index- L and ending at index- R (both inclusive) will be a palindrome if
(prefix[R + 1] – prefix[L]) / (101L) = (suffix [n – L] – suffix [n – R- 1] ) / (101n – R – 1)
The rest part is just implementation.
The function computerPowers() in the program computes the powers of 101 using dynamic programming.
Overflow Issues:
As, we can see that the hash values and the reverse hash values can become huge for even the small strings of length – 8. Since C and C++ doesn’t provide support for such large numbers, so it will cause overflows. To avoid this we will take modulo of a prime (a prime number is chosen for some specific mathematical reasons). We choose the biggest possible prime which fits in an integer value. The best such value is 1000000007. Hence all the operations are done modulo 1000000007. However, Java and Python has no such issues and can be implemented without the modulo operator. The fundamental modulo operations which are used extensively in the program are listed below.
1) Addition (a + b) %M = (a %M + b % M) % M
2) Multiplication (a * b) % M = (a * b) % M
This property is used by modPow() function which computes power of a number modulo M
3) Mixture of addition and multiplication
(a * x + b * y + c) % M = ( (a * x) % M +(b * y) % M+ c % M ) % M
4) Subtraction
(a – b) % M = (a % M – b % M + M) % M [Correct]
(a – b) % M = (a % M – b % M) % M [Wrong]
5) Division
(a / b) % M = (a * MMI(b)) % M
Where MMI() is a function to calculate Modulo Multiplicative Inverse. In our program this is implemented by the function- findMMI().
Below are the detailed steps.
- Given a string
str[]
, we compute the prefix hash as:
prefix[0] = 0
[Tex]prefix[i] = str[0] + str[1] * 101 + str[2] * 101 ^ 2 + … + str[i – 1] * 101 ^ {i – 1}[/Tex] - Using prefix hashing, the hash value of a substring
str[L:R]
can be found as:
[Tex]hash(L, R) = prefix[R + 1] – prefix[L][/Tex] - Similar to this, we compute the suffix hash as:
suffix[0] = 0
[Tex]suffix[i] = str[n – 1] + str[n – 2] * 101 + str[n – 3] * 101 ^ 2 + … + str[n – i] * 101 ^ {i – 1}[/Tex] - Using suffix hashing, the reverse hash of a substring str[L:R] can be found as:
[Tex]reverseHash(L, R) = suffix[n – L] – suffix[n – R – 1][/Tex] - A substring str[L:R] is a palindrome if:
[Tex]prefix[R + 1] – prefix[L] / 101 ^ L = suffix[n – L] – suffix[n – R – 1] / 101 ^ {n – R – 1}[/Tex] - This means the hash values must match after adjusting for position shifts.
- To avoid integer overflow, use mod 1e9 + 7. The mod operation has following properties:
- Addition: (a + b) % mod = ((a % mod) + (b % mod)) % mod
- Multiplication: (a * b) % mod = ((a % mod) * (b % mod)) % mod
- Subtraction: (a – b) % mod = ((a % mod) – (b % mod) + mod) % mod
- Division: Used modular multiplicative inverse via Fermat’s Theorem.
- Precompute powers of 101 using dynamic programming (
computePowers()
). - Build prefix and suffix hash tables.
C++
#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define int long long int
// function to calculate the prefix hash
vector<int> prefixHash(string &str, vector<int> &power) {
int n = str.size();
vector<int> prefix(n + 1);
prefix[0] = 0;
prefix[1] = str[0] - 'a' + 1;
for (int i = 2; i <= n; i++) {
prefix[i] = (prefix[i - 1] +
(str[i - 1] - 'a' + 1) * power[i - 1]) % mod;
}
return prefix;
}
// function to calculate the suffix hash
vector<int> suffixHash(string &str, vector<int> &power) {
int n = str.size();
vector<int> suffix(n + 1);
suffix[0] = 0;
suffix[1] = str[n - 1] - 'a' + 1;
for (int i = n - 2, j = 2; i >= 0 && j <= n; i--, j++) {
suffix[j] = (suffix[j - 1] +
(str[i] - 'a' + 1) * power[j - 1]) % mod;
}
return suffix;
}
// A Function to find pow (base, exponent) % MOD
// in log (exponent) time
int modPow(int base, int exp) {
if (exp == 0) return 1;
if (exp == 1) return base % mod;
int temp = modPow(base, exp / 2);
if (exp % 2 == 0) {
return (temp * temp) % mod;
} else {
return (((temp * temp) % mod) * base) % mod;
}
}
// function to calculate modulo multiplicative inverse
int findMMI(int n) {
return modPow(n, mod - 2);
}
// function to solve the queries
int solveQuery(string &str, vector<int> &query,
vector<int> &prefix, vector<int> &suffix, vector<int> &power) {
int l = query[0], r = query[1];
int n = str.size();
// hash value of substring [l, r]
int hash = (((prefix[r + 1] - prefix[l] + mod) %
mod) * findMMI(power[l])) % mod;
// reverse hash value of substring [l, r]
int reverseHash = (((suffix[n - l] - suffix[n - r - 1] +
mod) % mod) * (findMMI(power[n - r - 1]) % mod)) % mod;
// check if both hashes are equal
return (hash == reverseHash) ? 1 : 0;
}
// to compute the powers of 101
vector<int> computePowers(int n) {
vector<int> power(n + 1);
power[0] = 1;
for (int i = 1; i <= n; i++) {
power[i] = (power[i - 1] * 101) % mod;
}
return power;
}
// function to check if the substring
// is a palindrome for each query
vector<int> palindromeQueries(string str,
vector<vector<int>>& queries) {
int n = str.size();
int q = queries.size();
// to store the powers of 101
vector<int> power = computePowers(n);
// compute prefix and suffix hash arrays
vector<int> prefix = prefixHash(str, power);
vector<int> suffix = suffixHash(str, power);
// compute the results
vector<int> res(q);
for(int i = 0; i < q; i++) {
res[i] = solveQuery(str, queries[i], prefix, suffix, power);
}
return res;
}
signed main() {
string str = "abaaabaaaba";
vector<vector<int>> queries =
{{0, 10}, {5, 8}, {2, 5}, {5, 9}};
vector<int> res =
palindromeQueries(str, queries);
for(auto i: res) {
cout << i << " ";
}
return 0;
}
Java
import java.util.*;
public class GfG {
static final long mod = 1000000007;
// function to calculate the prefix hash
static long[] prefixHash(String str, long[] power) {
int n = str.length();
long[] prefix = new long[n + 1];
prefix[0] = 0;
prefix[1] = str.charAt(0) - 'a' + 1;
for (int i = 2; i <= n; i++) {
prefix[i] = (prefix[i - 1] +
(str.charAt(i - 1) - 'a' + 1) * power[i - 1]) % mod;
}
return prefix;
}
// function to calculate the suffix hash
static long[] suffixHash(String str, long[] power) {
int n = str.length();
long[] suffix = new long[n + 1];
suffix[0] = 0;
suffix[1] = str.charAt(n - 1) - 'a' + 1;
for (int i = n - 2, j = 2; i >= 0 && j <= n; i--, j++) {
suffix[j] = (suffix[j - 1] +
(str.charAt(i) - 'a' + 1) * power[j - 1]) % mod;
}
return suffix;
}
// A Function to find pow (base, exponent) % MOD
// in log (exponent) time
static long modPow(long base, long exp) {
if (exp == 0) return 1;
if (exp == 1) return base % mod;
long temp = modPow(base, exp / 2);
if (exp % 2 == 0) {
return (temp * temp) % mod;
} else {
return ((temp * temp) % mod * base) % mod;
}
}
// function to calculate modulo multiplicative inverse
static long findMMI(long n) {
return modPow(n, mod - 2);
}
// function to solve the queries
static int solveQuery(String str, int[] query,
long[] prefix, long[] suffix, long[] power) {
int l = query[0], r = query[1];
int n = str.length();
// hash value of substring [l, r]
long hash = (((prefix[r + 1] - prefix[l] + mod)
% mod) * findMMI(power[l])) % mod;
// reverse hash value of substring [l, r]
long reverseHash = (((suffix[n - l] - suffix[n - r - 1] +
mod) % mod) * (findMMI(power[n - r - 1]) % mod)) % mod;
// check if both hashes are equal
return (hash == reverseHash) ? 1 : 0;
}
// to compute the powers of 101
static long[] computePowers(int n) {
long[] power = new long[n + 1];
power[0] = 1;
for (int i = 1; i <= n; i++) {
power[i] = (power[i - 1] * 101) % mod;
}
return power;
}
// function to check if the substring
// is a palindrome for each query
static int[] palindromeQueries(String str,
List<int[]> queries) {
int n = str.length();
int q = queries.size();
// to store the powers of 101
long[] power = computePowers(n);
// compute prefix and suffix hash arrays
long[] prefix = prefixHash(str, power);
long[] suffix = suffixHash(str, power);
// compute the results
int[] res = new int[q];
for (int i = 0; i < q; i++) {
res[i] = solveQuery(str,
queries.get(i), prefix, suffix, power);
}
return res;
}
public static void main(String[] args) {
String str = "abaaabaaaba";
List<int[]> queries = new ArrayList<>();
queries.add(new int[]{0, 10});
queries.add(new int[]{5, 8});
queries.add(new int[]{2, 5});
queries.add(new int[]{5, 9});
int[] res = palindromeQueries(str, queries);
for (int i : res) {
System.out.print(i + " ");
}
}
}
Python
mod = 1000000007
# function to calculate the prefix hash
def prefixHash(str, power):
n = len(str)
prefix = [0] * (n + 1)
prefix[0] = 0
prefix[1] = ord(str[0]) - ord('a') + 1
for i in range(2, n + 1):
prefix[i] = (prefix[i - 1] +
(ord(str[i - 1]) - ord('a') + 1) * power[i - 1]) % mod
return prefix
# function to calculate the suffix hash
def suffixHash(str, power):
n = len(str)
suffix = [0] * (n + 1)
suffix[0] = 0
suffix[1] = ord(str[n - 1]) - ord('a') + 1
j = 2
for i in range(n - 2, -1, -1):
if j <= n:
suffix[j] = (suffix[j - 1] +
(ord(str[i]) - ord('a') + 1) * power[j - 1]) % mod
j += 1
return suffix
# A Function to find pow (base, exponent) % MOD
# in log (exponent) time
def modPow(base, exp):
if exp == 0:
return 1
if exp == 1:
return base % mod
temp = modPow(base, exp // 2)
if exp % 2 == 0:
return (temp * temp) % mod
else:
return ((temp * temp) % mod * base) % mod
# function to calculate modulo multiplicative inverse
def findMMI(n):
return modPow(n, mod - 2)
# function to solve the queries
def solveQuery(str, query, prefix, suffix, power):
l = query[0]
r = query[1]
n = len(str)
# hash value of substring [l, r]
hash_val = (((prefix[r + 1] - prefix[l] + mod) % mod)
* findMMI(power[l])) % mod
# reverse hash value of substring [l, r]
reverseHash = (((suffix[n - l] - suffix[n - r - 1] + mod)
% mod) * (findMMI(power[n - r - 1]) % mod)) % mod
# check if both hashes are equal
return 1 if (hash_val == reverseHash) else 0
# to compute the powers of 101
def computePowers(n):
power = [0] * (n + 1)
power[0] = 1
for i in range(1, n + 1):
power[i] = (power[i - 1] * 101) % mod
return power
# function to check if the substring
# is a palindrome for each query
def palindromeQueries(str, queries):
n = len(str)
q = len(queries)
# to store the powers of 101
power = computePowers(n)
# compute prefix and suffix hash arrays
prefix = prefixHash(str, power)
suffix = suffixHash(str, power)
# compute the results
res = [0] * q
for i in range(q):
res[i] = solveQuery(str, queries[i], prefix, suffix, power)
return res
if __name__ == "__main__":
str = "abaaabaaaba"
queries = [[0, 10], [5, 8], [2, 5], [5, 9]]
res = palindromeQueries(str, queries)
del str
print(" ".join(map(str, res)))
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class GfG {
const long mod = 1000000007;
// function to calculate the prefix hash
static long[] prefixHash(string str, long[] power) {
int n = str.Length;
long[] prefix = new long[n + 1];
prefix[0] = 0;
prefix[1] = str[0] - 'a' + 1;
for (int i = 2; i <= n; i++) {
prefix[i] = (prefix[i - 1] +
(str[i - 1] - 'a' + 1) * power[i - 1]) % mod;
}
return prefix;
}
// function to calculate the suffix hash
static long[] suffixHash(string str, long[] power) {
int n = str.Length;
long[] suffix = new long[n + 1];
suffix[0] = 0;
suffix[1] = str[n - 1] - 'a' + 1;
for (int i = n - 2, j = 2; i >= 0 && j <= n; i--, j++) {
suffix[j] = (suffix[j - 1] +
(str[i] - 'a' + 1) * power[j - 1]) % mod;
}
return suffix;
}
// A Function to find pow (base, exponent) % MOD
// in log (exponent) time
static long modPow(long baseVal, long exp) {
if (exp == 0) return 1;
if (exp == 1) return baseVal % mod;
long temp = modPow(baseVal, exp / 2);
if (exp % 2 == 0) {
return (temp * temp) % mod;
} else {
return ((temp * temp) % mod * baseVal) % mod;
}
}
// function to calculate modulo multiplicative inverse
static long findMMI(long n) {
return modPow(n, mod - 2);
}
// function to solve the queries
static int solveQuery(string str, int[] query,
long[] prefix, long[] suffix, long[] power) {
int l = query[0], r = query[1];
int n = str.Length;
// hash value of substring [l, r]
long hash = (((prefix[r + 1] - prefix[l] + mod)
% mod) * findMMI(power[l])) % mod;
// reverse hash value of substring [l, r]
long reverseHash = (((suffix[n - l] - suffix[n - r - 1] + mod)
% mod) * (findMMI(power[n - r - 1]) % mod)) % mod;
// check if both hashes are equal
return (hash == reverseHash) ? 1 : 0;
}
// to compute the powers of 101
static long[] computePowers(int n) {
long[] power = new long[n + 1];
power[0] = 1;
for (int i = 1; i <= n; i++) {
power[i] = (power[i - 1] * 101) % mod;
}
return power;
}
// function to check if the substring
// is a palindrome for each query
static int[] palindromeQueries(string str,
List<int[]> queries) {
int n = str.Length;
int q = queries.Count;
// to store the powers of 101
long[] power = computePowers(n);
// compute prefix and suffix hash arrays
long[] prefix = prefixHash(str, power);
long[] suffix = suffixHash(str, power);
// compute the results
int[] res = new int[q];
for (int i = 0; i < q; i++) {
res[i] = solveQuery(str, queries[i], prefix, suffix, power);
}
return res;
}
public static void Main(string[] args) {
string str = "abaaabaaaba";
List<int[]> queries = new List<int[]> {
new int[] {0, 10},
new int[] {5, 8},
new int[] {2, 5},
new int[] {5, 9}
};
int[] res = palindromeQueries(str, queries);
foreach (int i in res) {
Console.Write(i + " ");
}
}
}
JavaScript
const mod = 1000000007n;
// function to calculate the prefix hash
function prefixHash(str, power) {
let n = str.length;
let prefix = new Array(n + 1).fill(0n);
prefix[0] = 0n;
prefix[1] = BigInt(str.charCodeAt(0) - 'a'.charCodeAt(0) + 1);
for (let i = 2; i <= n; i++) {
prefix[i] = (prefix[i - 1] + (BigInt(str.charCodeAt(i - 1)
- 'a'.charCodeAt(0) + 1) * power[i - 1])) % mod;
}
return prefix;
}
// function to calculate the suffix hash
function suffixHash(str, power) {
let n = str.length;
let suffix = new Array(n + 1).fill(0n);
suffix[0] = 0n;
suffix[1] = BigInt(str.charCodeAt(n - 1) - 'a'.charCodeAt(0) + 1);
for (let i = n - 2, j = 2; i >= 0 && j <= n; i--, j++) {
suffix[j] = (suffix[j - 1] + (BigInt(str.charCodeAt(i)
- 'a'.charCodeAt(0) + 1) * power[j - 1])) % mod;
}
return suffix;
}
// A Function to find pow (base, exponent) % MOD
// in log (exponent) time
function modPow(base, exp) {
if (exp === 0n) return 1n;
if (exp === 1n) return base % mod;
let temp = modPow(base, exp / 2n);
if (exp % 2n === 0n) {
return (temp * temp) % mod;
} else {
return ((temp * temp) % mod * base) % mod;
}
}
// function to calculate modulo multiplicative inverse
function findMMI(n) {
return modPow(n, mod - 2n);
}
// function to solve the queries
function solveQuery(str, query, prefix, suffix, power) {
let l = query[0], r = query[1];
let n = str.length;
// hash value of substring [l, r]
let hash = (((prefix[r + 1] - prefix[l] + mod) % mod)
* findMMI(power[l])) % mod;
// reverse hash value of substring [l, r]
let reverseHash = (((suffix[n - l] - suffix[n - r - 1]
+ mod) % mod) * findMMI(power[n - r - 1])) % mod;
// check if both hashes are equal
return (hash === reverseHash) ? 1 : 0;
}
// to compute the powers of 101
function computePowers(n) {
let power = new Array(n + 1).fill(0n);
power[0] = 1n;
for (let i = 1; i <= n; i++) {
power[i] = (power[i - 1] * 101n) % mod;
}
return power;
}
// function to check if the substring
// is a palindrome for each query
function palindromeQueries(str, queries) {
let n = str.length;
let q = queries.length;
// to store the powers of 101
let power = computePowers(n);
// compute prefix and suffix hash arrays
let prefix = prefixHash(str, power);
let suffix = suffixHash(str, power);
// compute the results
let res = new Array(q);
for (let i = 0; i < q; i++) {
res[i] = solveQuery(str, queries[i], prefix, suffix, power);
}
return res;
}
function main() {
let str = "abaaabaaaba";
let queries = [[0, 10], [5, 8], [2, 5], [5, 9]];
let res = palindromeQueries(str, queries);
console.log(res.join(" "));
}
main();
Similar Reads
String in Data Structure
A string is a sequence of characters. The following facts make string an interesting data structure. Small set of elements. Unlike normal array, strings typically have smaller set of items. For example, lowercase English alphabet has only 26 characters. ASCII has only 256 characters.Strings are immu
3 min read
Introduction to Strings - Data Structure and Algorithm Tutorials
Strings are sequences of characters. The differences between a character array and a string are, a string is terminated with a special character â\0â and strings are typically immutable in most of the programming languages like Java, Python and JavaScript. Below are some examples of strings: "geeks"
7 min read
Applications, Advantages and Disadvantages of String
The String data structure is the backbone of programming languages and the building blocks of communication. String data structures are one of the most fundamental and widely used tools in computer science and programming. They allow for the representation and manipulation of text and character sequ
6 min read
String, Subsequence & Substring
What is a Substring? A substring is a contiguous part of a string, i.e., a string inside another string. In general, for an string of size n, there are n*(n+1)/2 non-empty substrings. For example, Consider the string "geeks", There are 15 non-empty substrings. The subarrays are: g, ge, gee, geek, ge
6 min read
Storage for Strings in C
In C, a string can be referred to either using a character pointer or as a character array. Strings as character arrays [GFGTABS] C char str[4] = "GfG"; /*One extra for string terminator*/ /* OR */ char str[4] = {âGâ, âfâ, âGâ, '\0'}; /* '\0' is string terminator */ [/GFGTA
5 min read
Strings in different language
Basic operations on String
Searching For Characters and Substring in a String in Java
Efficient String manipulation is very important in Java programming especially when working with text-based data. In this article, we will explore essential methods like indexOf(), contains(), and startsWith() to search characters and substrings within strings in Java. Searching for a Character in a
5 min read
Reverse a String â Complete Tutorial
Given a string s, the task is to reverse the string. Reversing a string means rearranging the characters such that the first character becomes the last, the second character becomes second last and so on. Examples: Input: s = "GeeksforGeeks"Output: "skeeGrofskeeG"Explanation : The first character G
14 min read
Left Rotation of a String
Given a string s and an integer d, the task is to left rotate the string by d positions. Examples: Input: s = "GeeksforGeeks", d = 2Output: "eksforGeeksGe" Explanation: After the first rotation, string s becomes "eeksforGeeksG" and after the second rotation, it becomes "eksforGeeksGe". Input: s = "q
15+ min read
Sort string of characters
Given a string of lowercase characters from 'a' - 'z'. We need to write a program to print the characters of this string in sorted order. Examples: Input : "dcab" Output : "abcd"Input : "geeksforgeeks"Output : "eeeefggkkorss" Naive Approach - O(n Log n) TimeA simple approach is to use sorting algori
5 min read
Frequency of Characters in Alphabetical Order
Given a string s, the task is to print the frequency of each of the characters of s in alphabetical order.Example: Input: s = "aabccccddd" Output: a2b1c4d3 Since it is already in alphabetical order, the frequency of the characters is returned for each character. Input: s = "geeksforgeeks" Output: e4
9 min read
Swap characters in a String
Given a String S of length N, two integers B and C, the task is to traverse characters starting from the beginning, swapping a character with the character after C places from it, i.e. swap characters at position i and (i + C)%N. Repeat this process B times, advancing one position at a time. Your ta
14 min read
C Program to Find the Length of a String
The length of a string is the number of characters in it without including the null character (â\0â). In this article, we will learn how to find the length of a string in C. The easiest way to find the string length is by using strlen() function from the C strings library. Let's take a look at an ex
2 min read
How to insert characters in a string at a certain position?
Given a string str and an array of indices chars[] that describes the indices in the original string where the characters will be added. For this post, let the character to be inserted in star (*). Each star should be inserted before the character at the given index. Return the modified string after
7 min read
Check if two strings are same or not
Given two strings, the task is to check if these two strings are identical(same) or not. Consider case sensitivity. Examples: Input: s1 = "abc", s2 = "abc" Output: Yes Input: s1 = "", s2 = "" Output: Yes Input: s1 = "GeeksforGeeks", s2 = "Geeks" Output: No Approach - By Using (==) in C++/Python/C#,
7 min read
Concatenating Two Strings in C
Concatenating two strings means appending one string at the end of another string. In this article, we will learn how to concatenate two strings in C. The most straightforward method to concatenate two strings is by using strcat() function. Let's take a look at an example: [GFGTABS] C #include <s
3 min read
Remove all occurrences of a character in a string
Given a string and a character, remove all the occurrences of the character in the string. Examples: Input : s = "geeksforgeeks" c = 'e'Output : s = "gksforgks"Input : s = "geeksforgeeks" c = 'g'Output : s = "eeksforeeks"Input : s = "geeksforgeeks" c = 'k'Output : s = "geesforgees" Using Built-In Me
2 min read
Binary String
Check if all bits can be made same by single flip
Given a binary string, find if it is possible to make all its digits equal (either all 0's or all 1's) by flipping exactly one bit. Input: 101Output: YeExplanation: In 101, the 0 can be flipped to make it all 1 Input: 11Output: NoExplanation: No matter whichever digit you flip, you will not get the
5 min read
Number of flips to make binary string alternate | Set 1
Given a binary string, that is it contains only 0s and 1s. We need to make this string a sequence of alternate characters by flipping some of the bits, our goal is to minimize the number of bits to be flipped. Examples : Input : str = â001â Output : 1 Minimum number of flips required = 1 We can flip
8 min read
Binary representation of next number
Given a binary string that represents binary representation of positive number n, the task is to find the binary representation of n+1. The binary input may or may not fit in an integer, so we need to return a string. Examples: Input: s = "10011"Output: "10100"Explanation: Here n = (19)10 = (10011)2
6 min read
Min flips of continuous characters to make all characters same in a string
Given a string consisting only of 1's and 0's. In one flip we can change any continuous sequence of this string. Find this minimum number of flips so the string consist of same characters only.Examples: Input : 00011110001110Output : 2We need to convert 1's sequenceso string consist of all 0's.Input
8 min read
Generate all binary strings without consecutive 1's
Given an integer, K. Generate all binary strings of size k without consecutive 1's. Examples: Input : K = 3 Output : 000 , 001 , 010 , 100 , 101 Input : K = 4 Output :0000 0001 0010 0100 0101 1000 1001 1010Idea behind that is IF string ends with '1' then we put only '0' at the end. IF string ends wi
15 min read
Find i'th Index character in a binary string obtained after n iterations
Given a decimal number m, convert it into a binary string and apply n iterations. In each iteration, 0 becomes "01" and 1 becomes "10". Find the (based on indexing) index character in the string after the nth iteration. Examples: Input : m = 5, n = 2, i = 3Output : 1Input : m = 3, n = 3, i = 6Output
6 min read
Substring and Subsequence
All substrings of a given String
Given a string s, containing lowercase alphabetical characters. The task is to print all non-empty substrings of the given string. Examples : Input : s = "abc"Output : "a", "ab", "abc", "b", "bc", "c" Input : s = "ab"Output : "a", "ab", "b" Input : s = "a"Output : "a" [Expected Approach] - Using Ite
9 min read
Print all subsequences of a string
Given a string, we have to find out all its subsequences of it. A String is said to be a subsequence of another String, if it can be obtained by deleting 0 or more character without changing its order. Examples: Input : abOutput : "", "a", "b", "ab" Input : abcOutput : "", "a", "b", "c", "ab", "ac",
12 min read
Count Distinct Subsequences
Given a string str of length n, your task is to find the count of distinct subsequences of it. Examples: Input: str = "gfg"Output: 7Explanation: The seven distinct subsequences are "", "g", "f", "gf", "fg", "gg" and "gfg" Input: str = "ggg"Output: 4Explanation: The four distinct subsequences are "",
14 min read
Count distinct occurrences as a subsequence
Given two strings pat and txt, where pat is always shorter than txt, count the distinct occurrences of pat as a subsequence in txt. Examples: Input: txt = abba, pat = abaOutput: 2Explanation: pat appears in txt as below three subsequences.[abba], [abba] Input: txt = banana, pat = banOutput: 3Explana
15+ min read
Longest Common Subsequence (LCS)
Given two strings, s1 and s2, the task is to find the length of the Longest Common Subsequence. If there is no common subsequence, return 0. A subsequence is a string generated from the original string by deleting 0 or more characters, without changing the relative order of the remaining characters.
15+ min read
Shortest Superstring Problem
Given a set of n strings arr[], find the smallest string that contains each string in the given set as substring. We may assume that no string in arr[] is substring of another string.Examples: Input: arr[] = {"geeks", "quiz", "for"}Output: geeksquizforExplanation: "geeksquizfor" contains all the thr
15+ min read
Printing Shortest Common Supersequence
Given two strings s1 and s2, find the shortest string which has both s1 and s2 as its sub-sequences. If multiple shortest super-sequence exists, print any one of them.Examples: Input: s1 = "geek", s2 = "eke"Output: geekeExplanation: String "geeke" has both string "geek" and "eke" as subsequences.Inp
9 min read
Shortest Common Supersequence
Given two strings s1 and s2, the task is to find the length of the shortest string that has both s1 and s2 as subsequences. Examples: Input: s1 = "geek", s2 = "eke"Output: 5Explanation: String "geeke" has both string "geek" and "eke" as subsequences. Input: s1 = "AGGTAB", s2 = "GXTXAYB"Output: 9Expl
15+ min read
Longest Repeating Subsequence
Given a string s, the task is to find the length of the longest repeating subsequence, such that the two subsequences don't have the same string character at the same position, i.e. any ith character in the two subsequences shouldn't have the same index in the original string. Examples: Input: s= "a
15+ min read
Longest Palindromic Subsequence (LPS)
Given a string s, find the length of the Longest Palindromic Subsequence in it. Note: The Longest Palindromic Subsequence (LPS) is the maximum-length subsequence of a given string that is also a Palindrome. Examples: Input: s = "bbabcbcab"Output: 7Explanation: Subsequence "babcbab" is the longest su
15+ min read
Longest Palindromic Substring
Given a string s, the task is to find the longest substring which is a palindrome. If there are multiple answers, then return the first appearing substring. Examples: Input: s = "forgeeksskeegfor" Output: "geeksskeeg"Explanation: There are several possible palindromic substrings like "kssk", "ss", "
12 min read
Palindrome
C Program to Check for Palindrome String
A string is said to be palindrome if the reverse of the string is the same as the string. In this article, we will learn how to check whether the given string is palindrome or not using C program. The simplest method to check for palindrome string is to reverse the given string and store it in a tem
4 min read
Check if a given string is a rotation of a palindrome
Given a string, check if it is a rotation of a palindrome. For example your function should return true for "aab" as it is a rotation of "aba". Examples: Input: str = "aaaad" Output: 1 // "aaaad" is a rotation of a palindrome "aadaa" Input: str = "abcd" Output: 0 // "abcd" is not a rotation of any p
15+ min read
Check if characters of a given string can be rearranged to form a palindrome
Given a string, Check if the characters of the given string can be rearranged to form a palindrome. For example characters of "geeksogeeks" can be rearranged to form a palindrome "geeksoskeeg", but characters of "geeksforgeeks" cannot be rearranged to form a palindrome. Recommended PracticeAnagram P
14 min read
Online algorithm for checking palindrome in a stream
Given a stream of characters (characters are received one by one), write a function that prints 'Yes' if a character makes the complete string palindrome, else prints 'No'. Examples: Input: str[] = "abcba"Output: a Yes // "a" is palindrome b No // "ab" is not palindrome c No // "abc" is not palindro
15+ min read
Print all Palindromic Partitions of a String using Bit Manipulation
Given a string, find all possible palindromic partitions of a given string. Note that this problem is different from Palindrome Partitioning Problem, there the task was to find the partitioning with minimum cuts in input string. Here we need to print all possible partitions. Example: Input: nitinOut
10 min read
Minimum Characters to Add at Front for Palindrome
Given a string s, the task is to find the minimum number of characters to be added to the front of s to make it palindrome. A palindrome string is a sequence of characters that reads the same forward and backward. Examples: Input: s = "abc"Output: 2Explanation: We can make above string palindrome as
12 min read
Make largest palindrome by changing at most K-digits
Given a string containing all digits, we need to convert this string to a palindrome by changing at most K digits. If many solutions are possible then print lexicographically largest one.Examples: Input : str = â43435â k = 3Output : "93939" Explanation:Lexicographically largest palindrome after 3 ch
15 min read
Minimum Deletions to Make a String Palindrome
Given a string s of length n, the task is to remove or delete the minimum number of characters from the string so that the resultant string is a palindrome. Note: The order of characters should be maintained. Examples : Input : s = "aebcbda"Output : 2Explanation: Remove characters 'e' and 'd'. Resul
15+ min read
Minimum insertions to form a palindrome with permutations allowed
Given a string of lowercase letters. Find minimum characters to be inserted in the string so that it can become palindrome. We can change the positions of characters in the string. Examples: Input: geeksforgeeksOutput: 2Explanation: geeksforgeeks can be changed as: geeksroforskeeg or geeksorfroskeeg
5 min read