You are given an array of n
strings strs
, all of the same length.
We may choose any deletion indices, and we delete all the characters in those indices for each string.
For example, if we have strs = ["abcdef","uvwxyz"]
and deletion indices {0, 2, 3}
, then the final array after deletions is ["bef", "vyz"]
.
Suppose we chose a set of deletion indices answer
such that after deletions, the final array has its elements in lexicographic order (i.e., strs[0] <= strs[1] <= strs[2] <= ... <= strs[n - 1]
). Return the minimum possible value of answer.length
.
Example 1:
Input: strs = ["ca","bb","ac"] Output: 1 Explanation: After deleting the first column, strs = ["a", "b", "c"]. Now strs is in lexicographic order (ie. strs[0] <= strs[1] <= strs[2]). We require at least 1 deletion since initially strs was not in lexicographic order, so the answer is 1.
Example 2:
Input: strs = ["xc","yb","za"] Output: 0 Explanation: strs is already in lexicographic order, so we do not need to delete anything. Note that the rows of strs are not necessarily in lexicographic order: i.e., it is NOT necessarily true that (strs[0][0] <= strs[0][1] <= ...)
Example 3:
Input: strs = ["zyx","wvu","tsr"] Output: 3 Explanation: We have to delete every column.
Constraints:
n == strs.length
1 <= n <= 100
1 <= strs[i].length <= 100
strs[i]
consists of lowercase English letters.This problem asks to find the minimum number of columns to delete from an array of strings to make the remaining columns lexicographically sorted. Lexicographically sorted means that each row, when read from left to right, is less than or equal to the next row.
The solution uses a greedy approach. We iterate through each column and check if deleting it is necessary to maintain lexicographical order. We keep track of whether each row is already sorted (relative to previous rows) using a boolean array cut
.
Initialization:
res
: Counts the number of columns deleted. Initialized to 0.cut
: A boolean array indicating whether a row is already sorted compared to the previous rows. Initialized to all false
.Iteration: The outer loop iterates through each column (j
) of the strings.
Column Check: The inner loop (i
) compares adjacent rows (i
and i+1
) in the current column. If A[i].charAt(j) > A[i+1].charAt(j)
, it means the column is not lexicographically sorted at this point. We increment res
(deleting the column) and proceed to the next column (continue search
).
Updating cut
: If a column is not deleted, we update cut
. If A[i].charAt(j) < A[i+1].charAt(j)
, it indicates that row i
is now sorted with respect to row i+1
for the columns examined so far, so cut[i]
is set to true
.
Return Value: Finally, res
(the number of deleted columns) is returned.
class Solution {
public int minDeletionSize(String[] A) {
if (A == null || A.length <= 1) {
return 0;
}
int len = A.length, wordLen = A[0].length(), res = 0;
boolean[] cut = new boolean[len];
search:
for (int j = 0; j < wordLen; j++) {
for (int i = 0; i < len - 1; i++) {
if (!cut[i] && A[i].charAt(j) > A[i + 1].charAt(j)) {
res += 1;
continue search; // Go to the next column if this one needs deleting
}
}
for (int i = 0; i < len - 1; i++) {
if (A[i].charAt(j) < A[i + 1].charAt(j)) {
cut[i] = true; // Mark row i as sorted (relative to previous)
}
}
}
return res;
}
}
The search
label is used to break out of the inner loop when a column needs to be deleted. The code efficiently determines the minimum number of column deletions required without unnecessary computations.
Time Complexity: O(m*n), where 'm' is the number of strings and 'n' is the length of each string. We iterate through each column and compare adjacent rows.
Space Complexity: O(m), due to the boolean array cut
which stores the sorted status for each row. The space used is proportional to the number of rows (strings).