Related:
LeetCode 944 - Delete Columns to Make Sorted
LeetCode 955 - Delete Columns to Make Sorted II
LeetCode 960 - Delete Columns to Make Sorted III
https://leetcode.com/problems/delete-columns-to-make-sorted-iii/
https://leetcode.com/articles/delete-columns-to-make-sorted-iii/
For all
LeetCode 944 - Delete Columns to Make Sorted
LeetCode 955 - Delete Columns to Make Sorted II
LeetCode 960 - Delete Columns to Make Sorted III
https://leetcode.com/problems/delete-columns-to-make-sorted-iii/
We are given an array
A
of N
lowercase letter strings, all of the same length.
Now, we may choose any set of deletion indices, and for each string, we delete all the characters in those indices.
For example, if we have an array
A = ["babca","bbazb"]
and deletion indices {0, 1, 4}
, then the final array after deletions is ["bc","az"]
.
Suppose we chose a set of deletion indices
D
such that after deletions, the final array has every element (row) in lexicographic order.
For clarity,
A[0]
is in lexicographic order (ie. A[0][0] <= A[0][1] <= ... <= A[0][A[0].length - 1]
), A[1]
is in lexicographic order (ie. A[1][0] <= A[1][1] <= ... <= A[1][A[1].length - 1]
), and so on.
Return the minimum possible value of
D.length
.
Example 1:
Input: ["babca","bbazb"] Output: 3 Explanation: After deleting columns 0, 1, and 4, the final array is A = ["bc", "az"]. Both these rows are individually in lexicographic order (ie. A[0][0] <= A[0][1] and A[1][0] <= A[1][1]). Note that A[0] > A[1] - the array A isn't necessarily in lexicographic order.
Example 2:
Input: ["edcba"] Output: 4 Explanation: If we delete less than 4 columns, the only row won't be lexicographically sorted.
Example 3:
Input: ["ghi","def","abc"] Output: 0 Explanation: All rows are already lexicographically sorted.
Note:
1 <= A.length <= 100
1 <= A[i].length <= 100
https://leetcode.com/articles/delete-columns-to-make-sorted-iii/
This is a tricky problem that is hard to build an intuition about.
First, lets try to find the number of columns to keep, instead of the number to delete. At the end, we can subtract to find the desired answer.
Now, let's say we must keep the first column
C
. The next column D
we keep must have all rows lexicographically sorted (ie. C[i] <= D[i]
), and we can say that we have deleted all columns between C
and D
.
Now, we can use dynamic programming to solve the problem in this manner. Let
dp[k]
be the number of columns that are kept in answering the question for input [row[k:] for row in A]
. The above gives a simple recursion for dp[k]
.- Time Complexity: , where is the length of
A
, and is the length of each word inA
.
public int minDeletionSize(String[] A) {
int W = A[0].length();
int[] dp = new int[W];
Arrays.fill(dp, 1);
for (int i = W - 2; i >= 0; --i)
search: for (int j = i + 1; j < W; ++j) {
for (String row : A)
if (row.charAt(i) > row.charAt(j))
continue search;
dp[i] = Math.max(dp[i], 1 + dp[j]);
}
int kept = 0;
for (int x : dp)
kept = Math.max(kept, x);
return W - kept;
}
https://leetcode.com/problems/delete-columns-to-make-sorted-iii/discuss/205679/C%2B%2BJavaPython-Maximum-Increasing-Subsequence
Take
=> The final array has every row in lexicographic order.
=> The elements in final state is in increasing order.
=> The final elements is a sub sequence of initial array.
=> Transform the problem to find the maximum increasing sub sequence.
n
cols as n
elements, so we have an array of n
elements.=> The final array has every row in lexicographic order.
=> The elements in final state is in increasing order.
=> The final elements is a sub sequence of initial array.
=> Transform the problem to find the maximum increasing sub sequence.
Explanation
Now let's talking about how to find maximum increasing subsequence.
Here we apply a O(N^2) dp solution.
Now let's talking about how to find maximum increasing subsequence.
Here we apply a O(N^2) dp solution.
dp[i]
means the longest subsequence ends with i
-th element.For all
j < i
, if A[][j] < A[][i]
, then dp[j] = max(dp[j], dp[i] + 1)
public int minDeletionSize(String[] A) {
int m = A.length, n = A[0].length(), res = n - 1, k;
int[] dp = new int[n];
Arrays.fill(dp, 1);
for (int j = 0; j < n; ++j) {
for (int i = 0; i < j; ++i) {
for (k = 0; k < m; ++k) {
if (A[k].charAt(i) > A[k].charAt(j)) break;
}
if (k == m && dp[i] + 1 > dp[j])
dp[j] = dp[i] + 1;
}
res = Math.min(res, n - dp[j]);
}
return res;
}