22. Minimum Deletions

The problem can be found at the following link: ๐Ÿ”— Question Link

๐Ÿงฉ Problem Description

Given a string s, the task is to determine the minimum number of characters that must be deleted from s to convert it into a palindrome. The relative order of remaining characters must be preserved.

To solve this, we must maximize the length of the longest palindromic subsequence (LPS) and subtract its length from the original string length.

๐Ÿ’ฌ Key Insight:

  • The minimum number of deletions = len(s) - LPS(s)

  • Where LPS(s) is the length of the Longest Palindromic Subsequence of s.

๐Ÿ“˜ Examples

Example 1:

Input:

s = "aebcbda"

Output:

2

Explanation:

The LPS is "abcba" (length = 5). Minimum deletions = 7 - 5 = 2.

Example 2:

Input:

s = "geeksforgeeks"

Output:

8

Explanation:

The LPS is "eeggee" or "eefeef" (length = 5). Deletions = 13 - 5 = 8.

๐Ÿ”’ Constraints

  • $1 \leq \text{length of } s \leq 10^3$

โœ… My Approach

Bottom-Up 1D Dynamic Programming (Longest Palindromic Subsequence)

We compute the Longest Palindromic Subsequence (LPS) using dynamic programming. This optimized implementation uses only two 1D arrays (dp and prev) to store intermediate LPS lengths.

Algorithm Steps:

  1. Initialize two 1D arrays of size n: dp and prev.

  2. Start from the end of the string and move backward:

    • For each character s[i]:

      • Set dp[i] = 1 (each character is a palindrome of length 1).

      • Iterate j from i+1 to n-1:

        • If s[i] == s[j], set dp[j] = prev[j-1] + 2.

        • Else, set dp[j] = max(prev[j], dp[j-1]).

    • Copy dp to prev for the next iteration.

  3. Return n - dp[n-1], which is the minimum number of deletions.

๐Ÿงฎ Time and Auxiliary Space Complexity

  • Expected Time Complexity: O(nยฒ), because we compute values for all pairs (i, j) where i < j.

  • Expected Auxiliary Space Complexity: O(n), as we only use two arrays of size n.

๐Ÿง  Code (C++)

class Solution {
  public:
    int minDeletions(string &s) {
        int n = s.size();
        vector<int> dp(n), prev(n);
        for (int i = n - 1; i >= 0; --i) {
            dp[i] = 1;
            for (int j = i + 1; j < n; ++j)
                dp[j] = s[i] == s[j] ? prev[j - 1] + 2 : max(prev[j], dp[j - 1]);
            prev = dp;
        }
        return n - dp[n - 1];
    }
};
โšก Alternative Approaches

๐Ÿ“Š 2๏ธโƒฃ LCS with Reversed String (Bottom-Up 2D DP)

Algorithm Steps:

  1. Reverse the input string s to get t.

  2. Compute the Longest Common Subsequence (LCS) between s and t using a 2D table.

  3. The LCS of s and its reverse is the Longest Palindromic Subsequence (LPS).

  4. Return s.length() - LPS.

class Solution {
  public:
    int minDeletions(string s) {
        int n = s.size();
        string t = s;
        reverse(t.begin(), t.end());
        vector<vector<int>> dp(n + 1, vector<int>(n + 1));
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= n; ++j)
                dp[i][j] = s[i - 1] == t[j - 1] ? 1 + dp[i - 1][j - 1] : max(dp[i - 1][j], dp[i][j - 1]);
        return n - dp[n][n];
    }
};

โœ… Why This Approach?

  • Classic LCS technique reused to find LPS.

  • Easy to understand and debug.

๐Ÿ“ Complexity Analysis:

  • Time: O(nยฒ)

  • Auxiliary Space: O(nยฒ)

๐Ÿ“Š 3๏ธโƒฃ LCS with Reversed String (Space Optimized)

Algorithm Steps:

  1. Reverse the string s to get t.

  2. Use two 1D vectors to compute LCS between s and t in a space-optimized way.

  3. Result = s.length() - LCS.

class Solution {
  public:
    int minDeletions(string s) {
        int n = s.size();
        string t = s;
        reverse(t.begin(), t.end());
        vector<int> prev(n + 1), curr(n + 1);
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j)
                curr[j] = s[i - 1] == t[j - 1] ? 1 + prev[j - 1] : max(prev[j], curr[j - 1]);
            swap(prev, curr);
        }
        return n - prev[n];
    }
};

โœ… Why This Approach?

  • Minimizes memory use with only two rows.

  • Retains full accuracy and speed of 2D DP.

๐Ÿ“ Complexity Analysis:

  • Time: O(nยฒ)

  • Auxiliary Space: O(n)

๐Ÿ†š Comparison of Approaches

Approach

โฑ๏ธ Time

๐Ÿ—‚๏ธ Space

โœ… Pros

โš ๏ธ Cons

Original (1D DP from end)

๐ŸŸข O(nยฒ)

๐ŸŸข O(n)

Compact, direct LPS logic

Harder to grasp for beginners

LCS with Reversed (2D DP)

๐ŸŸข O(nยฒ)

๐Ÿ”ธ O(nยฒ)

Classic, easy to write

Higher memory usage

LCS with Reversed (Space Optimized)

๐ŸŸข O(nยฒ)

๐ŸŸข O(n)

Balanced: space-efficient + clear

Slightly longer to implement

โœ… Best Choice?

Scenario

Recommended Approach

Space optimized solution

๐Ÿฅ‡ Original 1D DP from end

Beginner-friendly or educational purpose

๐Ÿฅˆ LCS with Reversed (2D DP)

Balanced readability + performance

๐Ÿฅ‰ LCS with Reversed (Optimized)

๐Ÿง‘โ€๐Ÿ’ป Code (Java)

class Solution {
    static int minDeletions(String s) {
        int n = s.length();
        int[] dp = new int[n], prev = new int[n];
        for (int i = n - 1; i >= 0; --i) {
            dp[i] = 1;
            for (int j = i + 1; j < n; ++j)
                dp[j] = s.charAt(i) == s.charAt(j) ? prev[j - 1] + 2 : Math.max(prev[j], dp[j - 1]);
            prev = dp.clone();
        }
        return n - dp[n - 1];
    }
}

๐Ÿ Code (Python)

class Solution:
    def minDeletions(self, s):
        n = len(s)
        dp = [0] * n
        prev = [0] * n
        for i in range(n - 1, -1, -1):
            dp[i] = 1
            for j in range(i + 1, n):
                dp[j] = prev[j - 1] + 2 if s[i] == s[j] else max(prev[j], dp[j - 1])
            prev = dp[:]
        return n - dp[-1]

๐Ÿง  Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: ๐Ÿ“ฌ Any Questions?. Letโ€™s make this learning journey more collaborative!

โญ If you find this helpful, please give this repository a star! โญ


๐Ÿ“Visitor Count

Last updated