DEV Community

Dolly Sharma
Dolly Sharma

Posted on

πŸ“˜ Minimum Insertions to Make a String Palindrome

πŸ”Ή Key Idea (MOST IMPORTANT)

πŸ‘‰ Use Longest Palindromic Subsequence (LPS)

Minimum Insertions = n - LPS
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή Why this works?

  • LPS = longest part already palindrome
  • Remaining characters must be inserted to fix symmetry

πŸ‘‰ So:

Total characters βˆ’ already palindrome part = insertions needed


πŸ”Ή Convert to LCS

LPS(s) = LCS(s, reverse(s))
Enter fullscreen mode Exit fullscreen mode

πŸ”₯ Final Formula

Min Insertions = n - LCS(s, reverse(s))
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή Example

s = "abcaa"
Enter fullscreen mode Exit fullscreen mode

Reverse:

"aacba"
Enter fullscreen mode Exit fullscreen mode

πŸ‘‰ LCS = "aca" β†’ length = 3

Min Insertions = 5 - 3 = 2
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή Code (C++)

int lcs(string s1, string s2) {
    int n = s1.size(), m = s2.size();
    vector<vector<int>> dp(n+1, vector<int>(m+1, 0));

    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            if(s1[i-1] == s2[j-1])
                dp[i][j] = 1 + dp[i-1][j-1];
            else
                dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
        }
    }
    return dp[n][m];
}

int minInsertions(string s) {
    string t = s;
    reverse(t.begin(), t.end());

    int lps = lcs(s, t);
    return s.size() - lps;
}
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή Space Optimized πŸš€

int lcs(string s1, string s2) {
    int n = s1.size(), m = s2.size();
    vector<int> prev(m+1, 0), curr(m+1, 0);

    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            if(s1[i-1] == s2[j-1])
                curr[j] = 1 + prev[j-1];
            else
                curr[j] = max(prev[j], curr[j-1]);
        }
        prev = curr;
    }
    return prev[m];
}
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή Alternative DP (Direct without LCS)

πŸ‘‰ Define:

dp[i][j] = min insertions to make s[i..j] palindrome
Enter fullscreen mode Exit fullscreen mode

Transition:

  • If match:
dp[i][j] = dp[i+1][j-1]
Enter fullscreen mode Exit fullscreen mode
  • If not:
dp[i][j] = 1 + min(dp[i+1][j], dp[i][j-1])
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή Code (Direct DP)

int minInsertions(string s) {
    int n = s.size();
    vector<vector<int>> dp(n, vector<int>(n, 0));

    for(int len = 2; len <= n; len++){
        for(int i = 0; i + len - 1 < n; i++){
            int j = i + len - 1;

            if(s[i] == s[j])
                dp[i][j] = dp[i+1][j-1];
            else
                dp[i][j] = 1 + min(dp[i+1][j], dp[i][j-1]);
        }
    }

    return dp[0][n-1];
}
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή Complexity

Approach Time Space
LCS-based O(nΒ²) O(nΒ²) / O(n)
Direct DP O(nΒ²) O(nΒ²)

🧠 Key Pattern

πŸ‘‰ Whenever you see:

  • β€œMake palindrome”
  • β€œMinimum insert/delete”

➑️ Think:

Use LPS (LCS with reverse)
Enter fullscreen mode Exit fullscreen mode

πŸ”₯ Interview Tip

If asked:

β€œMinimum insertions to make palindrome?”

πŸ‘‰ Answer:

β€œWe compute LPS using LCS with reverse string, then subtract from length.”


⚑ Summary

  • Convert β†’ LPS
  • LPS β†’ LCS(s, reverse(s))
  • Answer β†’ n - LPS

πŸ“˜ Best Optimized Approach

(From Dynamic Programming)


πŸ”Ή Final Optimized Idea

We use:

Min Insertions = n - LCS(s, reverse(s))
Enter fullscreen mode Exit fullscreen mode

πŸ‘‰ Optimize LCS to O(n) space


πŸ”₯ Fully Optimized Code (O(nΒ²) time, O(n) space)

int minInsertions(string s) {
    int n = s.size();

    string t = s;
    reverse(t.begin(), t.end());

    vector<int> prev(n+1, 0), curr(n+1, 0);

    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            if(s[i-1] == t[j-1])
                curr[j] = 1 + prev[j-1];
            else
                curr[j] = max(prev[j], curr[j-1]);
        }
        prev = curr;
    }

    int lps = prev[n];
    return n - lps;
}
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή Space Complexity

Approach Space
Normal DP O(nΒ²)
Optimized (above) βœ… O(n)

πŸ”₯ Can we optimize more?

πŸ‘‰ ❌ NO (for general case)

Why?

  • You must compare all pairs β†’ needs O(nΒ²) time
  • LCS inherently requires quadratic time

πŸ”Ή Alternative (Direct DP optimized?)

πŸ‘‰ Direct DP:

dp[i][j] = min insertions
Enter fullscreen mode Exit fullscreen mode

❌ Cannot reduce to O(n) easily
πŸ‘‰ Because it depends on:

  • dp[i+1][j]
  • dp[i][j-1]
  • dp[i+1][j-1]

🧠 Final Takeaway

πŸ‘‰ Best you can do:

Metric Optimal
Time O(nΒ²)
Space βœ… O(n)

⚑ Interview Answer (Perfect πŸ”₯)

If asked:

β€œCan you optimize space?”

πŸ‘‰ Say:

β€œYes, by computing LCS with a 1D DP array, reducing space to O(n) while keeping time O(nΒ²). Further optimization isn’t possible due to dependency structure.”


πŸš€ Extra Insight (Advanced)

πŸ‘‰ If asked harder:

  • You can use Hirschberg’s Algorithm
  • Space β†’ O(n)
  • Still O(nΒ²) time
  • Can reconstruct palindrome too

If you want next πŸš€
I can show:
βœ… Build the actual palindrome string (very important)
βœ… Minimum deletions version
βœ… Hard interview problems

Just tell me πŸ‘

Top comments (0)