Forming palindrome using at most one deletion in JavaScript

We need to write a JavaScript function that checks if a string can be made into a palindrome by deleting at most one character.

Problem

Given a string, determine if it can become a palindrome after removing at most one character. A palindrome reads the same forwards and backwards.

For example, with the input string 'dr.awkward', we can remove the '.' character to get 'drawkward', which is a palindrome.

Algorithm Approach

We use a two-pointer technique:

  1. Compare characters from both ends moving inward
  2. When we find a mismatch, try removing either the left or right character
  3. Check if the remaining substring is a palindrome

Example Implementation

const str = 'dr.awkward';

const validPalindrome = (str = '') => {
    // Helper function to check if substring is palindrome
    const isPalindrome = (left, right) => {
        for (let i = left; i <= Math.floor((left + right) / 2); i++) {
            if (str[i] !== str[right - (i - left)]) {
                return false;
            }
        }
        return true;
    };
    
    // Main logic using two pointers
    for (let i = 0; i <= Math.floor(str.length / 2); i++) {
        const right = str.length - 1 - i;
        
        if (str[i] !== str[right]) {
            // Try removing left character OR right character
            return isPalindrome(i, right - 1) || isPalindrome(i + 1, right);
        }
    }
    
    return true; // Already a palindrome
};

console.log(validPalindrome(str));
console.log(validPalindrome('racecar'));     // Already palindrome
console.log(validPalindrome('abcdef'));      // Cannot form palindrome
true
true
false

Step-by-Step Breakdown

Let's trace through 'dr.awkward':

const traceExample = (str) => {
    console.log(`Checking: "${str}"`);
    
    for (let i = 0; i <= Math.floor(str.length / 2); i++) {
        const right = str.length - 1 - i;
        console.log(`Comparing str[${i}] = '${str[i]}' with str[${right}] = '${str[right]}'`);
        
        if (str[i] !== str[right]) {
            console.log(`Mismatch found! Trying to remove one character...`);
            return;
        }
    }
};

traceExample('dr.awkward');
Checking: "dr.awkward"
Comparing str[0] = 'd' with str[9] = 'd'
Comparing str[1] = 'r' with str[8] = 'r'
Comparing str[2] = '.' with str[7] = 'a'
Mismatch found! Trying to remove one character...

Test Cases

const testCases = [
    'dr.awkward',    // true - remove '.'
    'racecar',       // true - already palindrome
    'abcdef',        // false - cannot form palindrome
    'a',             // true - single character
    'ab',            // true - remove 'a' or 'b'
    'abc'            // false - cannot form palindrome
];

testCases.forEach(test => {
    console.log(`"${test}" -> ${validPalindrome(test)}`);
});
"dr.awkward" -> true
"racecar" -> true
"abcdef" -> false
"a" -> true
"ab" -> true
"abc" -> false

Time and Space Complexity

Aspect Complexity Explanation
Time O(n) Single pass through string, constant work per character
Space O(1) Only using variables, no additional data structures

Conclusion

The two-pointer approach efficiently solves the palindrome problem with at most one deletion in O(n) time. When characters don't match, we test both deletion possibilities to determine if a palindrome can be formed.

Updated on: 2026-03-15T23:19:00+05:30

245 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements