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
這道題說是給了一個字符串數組A,其中每個字符串的長度均相同,現在需要刪除一些特定位置上的字符,需要使得留下的字符是按照字母順序排列的,問最少需要刪除多少列。這道題需要借助題目中給的例子來理解,因為每個字符串長度相同,若每行放一個字符串,那么其實也可以看作是一個二維的字符數組,要刪除最少的列,使得每行都是有序的。實際上最差的情況就是每行都是倒序的,就要移除 n-1 列,只留下一列,若每行只有一個字符,則一定是符合題意。最好的情況就是給定每行已經都是有序的,則一列都不用移除,所以最終的結果是在一定的范圍之內的,即 [0, n-1],其中n是字符串的長度。假如只有一個字符串,為了使其有序,需要移除最小的列數,移除之后剩下的就是有序的。那么其實就是等同於找出該字符串中的最大遞增序列的長度,即之前那道 Longest Increasing Subsequence 的做法,然后用總長度減去這個 LIS 長度,即為最少移除的列數。若有多行的情況,這個 LIS 必須是所有行都滿足的,才符合題意。這里維護一個一維 dp 數組,其中 dp[i] 表示以 A[][i] 為結尾的最長遞增子串的長度,對於每一個 A[][i],從該行第一個數再搜索到i,此時由於有多行,每一行都要判斷一下,假如出現 A[][j] 大於 A[][i] 的情況,說明當前列不能組成 LIS,直接 break。只有每行都符合要求,並且 dp[j]+1 大於 d[i] 時,將 dp[i] 賦值為 dp[j]+1。當每次 dp[i] 更新了之后,用 n-dp[i] 來更新結果 res 即可,參見代碼如下:
class Solution {
public:
int minDeletionSize(vector<string>& A) {
int m = A.size(), n = A[0].size(), res = n - 1, k = 0;
vector<int> dp(n, 1);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < i; ++j) {
for (k = 0; k < m; ++k) {
if (A[k][j] > A[k][i]) break;
}
if (k == m && dp[j] + 1 > dp[i]) {
dp[i] = dp[j] + 1;
}
}
res = min(res, n - dp[i]);
}
return res;
}
};
討論:可能會有同學有疑問,會出現 dp[j]+1 小於 dp[i] 的情況么,其實是有的,比如 "cbbdabc",i = 6,是最后一個c,因為前面有前面出現了 bb,所以此時的 dp[6] = 3,當 j = 4 時,是中間的a,前面沒有比a小的字母,所以 dp[4] = 1,此時就出現了 dp[j]+1 小於 dp[i] 的情況。
Github 同步地址:
https://github.com/grandyang/leetcode/issues/960
類似題目:
Longest Increasing Subsequence
Delete Columns to Make Sorted II
參考資料:
https://leetcode.com/problems/delete-columns-to-make-sorted-iii/