class Solution:
def minDeletionSize(self, strs: List[str]) -> int:
n, m = len(strs), len(strs[0])
dp = [1] * m
for j in range(m):
for i in range(j):
if all(strs[row][i] <= strs[row][j] for row in range(n)):
dp[j] = max(dp[j], dp[i] + 1)
return m - max(dp)
class Solution {
public:
int minDeletionSize(vector<string>& strs) {
int n = strs.size(), m = strs[0].size();
vector<int> dp(m, 1);
for (int j = 0; j < m; ++j) {
for (int i = 0; i < j; ++i) {
bool valid = true;
for (int row = 0; row < n; ++row) {
if (strs[row][i] > strs[row][j]) {
valid = false;
break;
}
}
if (valid) {
dp[j] = max(dp[j], dp[i] + 1);
}
}
}
return m - *max_element(dp.begin(), dp.end());
}
};
class Solution {
public int minDeletionSize(String[] strs) {
int n = strs.length, m = strs[0].length();
int[] dp = new int[m];
Arrays.fill(dp, 1);
for (int j = 0; j < m; ++j) {
for (int i = 0; i < j; ++i) {
boolean valid = true;
for (int row = 0; row < n; ++row) {
if (strs[row].charAt(i) > strs[row].charAt(j)) {
valid = false;
break;
}
}
if (valid) {
dp[j] = Math.max(dp[j], dp[i] + 1);
}
}
}
int max = 0;
for (int d : dp) max = Math.max(max, d);
return m - max;
}
}
var minDeletionSize = function(strs) {
const n = strs.length, m = strs[0].length;
const dp = Array(m).fill(1);
for (let j = 0; j < m; ++j) {
for (let i = 0; i < j; ++i) {
let valid = true;
for (let row = 0; row < n; ++row) {
if (strs[row][i] > strs[row][j]) {
valid = false;
break;
}
}
if (valid) {
dp[j] = Math.max(dp[j], dp[i] + 1);
}
}
}
return m - Math.max(...dp);
};
You are given an array strs
where each element is a string of the same length. You can delete any number of columns from these strings (i.e., delete the same index from every string) so that the rows are lexicographically sorted. Your goal is to determine the minimum number of columns you must delete to achieve this.
strs
has the same length m
.At first glance, the problem resembles sorting or checking order, but with the twist that you can delete columns. The naive approach would be to try every possible subset of columns and check if the resulting rows are sorted, but this is not feasible for large inputs since the number of subsets grows exponentially.
Instead, we can think of the problem as finding the largest set of columns (in order) that we can keep so that the rows are sorted, and then delete the rest. This is similar to the Longest Increasing Subsequence (LIS) problem, but in two dimensions: we want to find the longest sequence of columns such that, for every pair of columns in the sequence, the characters in all rows are non-decreasing.
By focusing on which columns to keep rather than which to delete, we turn the original problem into a maximization problem. The minimum number of deletions is then the total number of columns minus the size of the largest valid subsequence of columns.
We solve the problem using dynamic programming, inspired by the Longest Increasing Subsequence (LIS) technique:
dp[j]
be the length of the longest valid sequence ending at column j
.
dp[j]
to 1, since each column can be a sequence by itself.
j
, look at all previous columns i < j
. If for every row r
, strs[r][i] <= strs[r][j]
, then column j
can follow column i
in the sequence. In this case, update dp[j]
as max(dp[j], dp[i] + 1)
.
m - max(dp)
, where m
is the total number of columns.
This approach ensures we only keep columns that maintain the required order in all rows, and we delete the minimal number of columns necessary.
Let's consider strs = ["babca", "bbazb"]
.
dp
step by step:
dp[0] = 1
.dp[1] = 1
.dp[2] = 1
.dp[3] = dp[0] + 1 = 2
.dp[3] = max(2, dp[1]+1)=2
.dp[3] = max(2, dp[2]+1)=2
.dp[4] = dp[1] + 1 = 2
.dp = [1, 1, 1, 2, 2]
, so the maximum is 2. We need to delete 5 - 2 = 3
columns.m
.
j
, we compare to all previous columns i
(O(m2)), and for each pair, we check all rows (O(n)).The problem is an application of the Longest Increasing Subsequence concept to columns of a string matrix, where the order must be maintained across all rows. By using dynamic programming, we efficiently find the largest set of columns to keep, ensuring the resulting rows are sorted, and thus minimize the number of columns to delete. This approach is both elegant and efficient, especially compared to the exponential brute-force solution.