Open In App

Palindrome Substring Queries in JavaScript

Last Updated : 17 Nov, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Here are the various approaches to check if a substring is a palindrome (a string that reads the same forward and backwards).

Using for Loop - Basic Approach

for loop iterates through each substring character from beginning to end for comparing each pair. If all pairs match, the substring is a palindrome.

JavaScript
function isPalindrome(s, start, end) {
    for (let i = 0; i < Math.floor((end - start + 1) / 2);
        i++) {
        if (s[start + i] !== s[end - i]) {
            return false;
        }
    }
    return true;
}

const s = "racecar";
console.log(
    isPalindrome(s, 0, s.length - 1));
console.log(isPalindrome(s, 0, 3)); 

Output

true
false

Using reverse(), join(), and split() Methods

In this approach, we extract the substring, reverse it, and check if it matches the original substring.

JavaScript
function isPalindrome(s, start, end) {
    const sub = s.substring(start, end + 1);
    return sub === sub.split("").reverse().join("");
}

const s = "racecar";
console.log(isPalindrome(s, 0, s.length - 1));
console.log(isPalindrome(s, 0, 3)); 

Output

true
false

Using Two-Pointer Technique

The two-pointer technique is an optimized approach where two pointers move toward the center from both ends, comparing characters. This method is efficient and does not require additional memory.

JavaScript
function isPalindrome(s, start, end) {
    while (start < end) {
        if (s[start] !== s[end]) {
            return false;
        }
        start++;
        end--;
    }
    return true;
}

const s = "madam";
console.log(isPalindrome(s, 0, s.length - 1));
console.log(isPalindrome(s, 1, 3));
console.log(isPalindrome(s, 0, 3)); 

Output

true
true
false

Using substring(), every(), and charAt() Methods

This approach uses substring() to extract a substring and every() with charAt() to compare corresponding characters from the start and end.

JavaScript
function isPalindrome(s, start, end) {
    const sub = s.substring(start, end + 1);
    return [...sub].every((char, i) => 
        char === sub.charAt(sub.length - 1 - i));
}

const s = "civic";
console.log(isPalindrome(s, 0, s.length - 1));
console.log(isPalindrome(s, 0, 3)); 

Output

true
false

Using Hashing and Rolling Hash - Advanced Approach

Hashing and rolling hash techniques are advanced ways to check for palindromes. They make checking efficient when there are many queries by storing hash values for quick comparisons.

JavaScript
// Helper function to calculate forward and backward hashes
function computeHashes(s) {
    const n = s.length;
    const base = 31;
    const mod = 1e9 + 7;

    // Arrays to store hash values and powers
    let forwardHash = Array(n + 1).fill(0);
    let backwardHash = Array(n + 1).fill(0);
    let power = Array(n + 1).fill(1);

    // Compute power of base for each position
    for (let i = 1; i <= n; i++) {
        power[i] = (power[i - 1] * base) % mod;
    }

    // Compute forward and backward hashes
    for (let i = 0; i < n; i++) {
        forwardHash[i + 1] = (forwardHash[i] * base + s.charCodeAt(i)) % mod;
        backwardHash[i + 1] =
            (backwardHash[i] * base + s.charCodeAt(n - 1 - i)) % mod;
    }

    return { forwardHash, backwardHash, power, mod };
}

// Function to check if a substring is palindrome using precomputed hashes
function isPalindromeWithHash(s, start, end, hashes) {
    const { forwardHash, backwardHash, power, mod } = hashes;

    // Compute the forward hash for the substring
    let forwardSubHash =
        (forwardHash[end + 1] -
            ((forwardHash[start] * power[end - start + 1]) % mod) +
            mod) %
        mod;

    // Compute the backward hash for the substring
    let backwardSubHash =
        (backwardHash[s.length - start] -
            ((backwardHash[s.length - end - 1] 
                * power[end - start + 1]) % mod) + mod) %
        mod;

    // Compare forward and backward hashes
    return forwardSubHash === backwardSubHash;
}

const s = "level";
const hashes = computeHashes(s);
console.log(isPalindromeWithHash(s, 0, 4, hashes));
console.log(isPalindromeWithHash(s, 1, 3, hashes));
console.log(isPalindromeWithHash(s, 0, 2, hashes));

Output

true
true
false

Next Article

Similar Reads