JavaScript Program to Find Minimum Insertions to Form a Palindrome

We are given a string and we have to find the minimum number of characters that we need to insert at any position to make the string a palindrome. A palindrome is a string that reads the same forwards and backwards. This problem can be solved using dynamic programming - we'll explore three approaches: recursive, memoization, and tabulation.

Understanding the Problem

For example, to make "abc" a palindrome, we need to insert 2 characters to get "abcba" or "cbabc". The key insight is that if characters at both ends match, we can focus on the substring between them. If they don't match, we need at least one insertion.

Recursive Approach

The recursive solution compares characters from both ends and makes recursive calls based on whether they match or not.

Example

// Function to find minimum of two numbers
function findMin(a, b) {
    return a < b ? a : b;
}

// Recursive function to find minimum insertions
function findAns(str, start, end) {
    // Base cases
    if (start > end) {
        return 0;
    }
    if (start == end) {
        return 0;
    }
    if (start == end - 1) {
        return str[start] == str[end] ? 0 : 1;
    }
    
    // If characters match, check substring
    if (str[start] == str[end]) {
        return findAns(str, start + 1, end - 1);
    } else {
        // If characters don't match, try inserting at either end
        return 1 + findMin(
            findAns(str, start, end - 1),
            findAns(str, start + 1, end)
        );
    }
}

// Test the function
var str = "abcd";
console.log("The minimum number of insertions required: " + findAns(str, 0, str.length - 1));
The minimum number of insertions required: 3

Time and Space Complexity

The time complexity is O(2^N) due to overlapping subproblems. The space complexity is O(N) for the recursion stack.

Memoization Approach

We can optimize the recursive solution by storing results of subproblems to avoid redundant calculations.

Example

// Function to find minimum of two numbers
function findMin(a, b) {
    return a < b ? a : b;
}

// Memoized function to find minimum insertions
function findAns(str, start, end, memo) {
    // Base cases
    if (start > end) {
        return 0;
    }
    if (start == end) {
        return 0;
    }
    if (start == end - 1) {
        return str[start] == str[end] ? 0 : 1;
    }
    
    // Check if already computed
    if (memo[start][end] != -1) {
        return memo[start][end];
    }
    
    // If characters match, check substring
    if (str[start] == str[end]) {
        memo[start][end] = findAns(str, start + 1, end - 1, memo);
    } else {
        // If characters don't match, try inserting at either end
        memo[start][end] = 1 + findMin(
            findAns(str, start, end - 1, memo),
            findAns(str, start + 1, end, memo)
        );
    }
    
    return memo[start][end];
}

// Test the function
var str = "abcd";
var n = str.length;

// Initialize memoization table
var memo = new Array(n);
for (var i = 0; i < n; i++) {
    memo[i] = new Array(n);
    for (var j = 0; j < n; j++) {
        memo[i][j] = -1;
    }
}

console.log("The minimum number of insertions required: " + findAns(str, 0, n - 1, memo));
The minimum number of insertions required: 3

Time and Space Complexity

The time complexity is O(N²) as each subproblem is solved only once. The space complexity is O(N²) for the memoization table plus O(N) for recursion stack.

Dynamic Programming (Tabulation) Approach

We can convert the memoized solution to an iterative bottom-up approach using a DP table.

Example

// Function to find minimum of two numbers
function findMin(a, b) {
    return a < b ? a : b;
}

// Dynamic programming function to find minimum insertions
function findAns(str) {
    var n = str.length;
    
    // Create DP table
    var dp = new Array(n);
    for (var i = 0; i < n; i++) {
        dp[i] = new Array(n);
        for (var j = 0; j < n; j++) {
            dp[i][j] = 0;
        }
    }
    
    // Fill the DP table
    for (var len = 2; len <= n; len++) {
        for (var start = 0; start <= n - len; start++) {
            var end = start + len - 1;
            
            if (str[start] == str[end]) {
                dp[start][end] = dp[start + 1][end - 1];
            } else {
                dp[start][end] = 1 + findMin(
                    dp[start][end - 1],
                    dp[start + 1][end]
                );
            }
        }
    }
    
    return dp[0][n - 1];
}

// Test the function
var str = "abcd";
console.log("The minimum number of insertions required: " + findAns(str));
The minimum number of insertions required: 3

Time and Space Complexity

The time complexity is O(N²) using nested loops. The space complexity is O(N²) for the DP table.

Approach Comparison

Approach Time Complexity Space Complexity Efficiency
Recursive O(2^N) O(N) Poor - exponential time
Memoization O(N²) O(N²) Good - eliminates redundancy
Tabulation O(N²) O(N²) Best - iterative, no recursion overhead

Conclusion

We implemented three approaches to find minimum insertions required to form a palindrome. The tabulation approach is most efficient as it eliminates recursion overhead while maintaining O(N²) time complexity. This problem demonstrates how dynamic programming can optimize exponential recursive solutions.

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

309 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements