Problem Statement in English

You’re given an array of n strings strs, all of the same length. We need to delete the minimum number of columns such that the remaining strings’ characters are lexicographically non-decreasing.

Return the minimum number of columns that need to be deleted.


Approach

This is one cool DP problem.

Couple things we need to keep in mind as we go into this:

  • If you think about it, we basically need an LIS (Longest Increasing Subsequence) on a per string basis (kind of)
  • It’s easier to come up with the number of columns to keep rather than the number of columns to delete

That’s it. Try it now.

For each column ($i^{th}$) we have to check all subsequent columns ($j^{th}$) on a per row basis to see if they can be kept.

If a pair of columns can be kept for every row in those columns, we can update our dp array.

Think about it - the dp update will be dp[i] = max(dp[i], 1 + dp[j]) where i is the current column and j is the subsequent column.

Finally, we return N - max(dp) where N is the total number of columns.

In my implementation the outer loop is reversed so that we can use previously computed dp values.


Solution in Python


class Solution:
    def minDeletionSize(self, strs: List[str]) -> int:
        N = len(strs[0])

        dp = [1] * N

        for i in reversed(range(N)):
            for j in range(i + 1, N):
                for row in strs:
                    if row[i] > row[j]:
                        break
                else:
                    dp[i] = max(dp[i], 1 + dp[j])

        return N - max(dp)

Complexity

  • Time: $O(N^2 \cdot M)$
    Since we have two nested loops iterating over the columns (N) and for each pair of columns, we are checking all rows (M) to see if the characters are in non-decreasing order.

  • Space: $O(N)$
    We are using a dp array of size N to store the length of the longest non-decreasing subsequence ending at each column.


Mistakes I Made

I had to look this one up :(


And we are done.