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
题目理解:
给定一个字符矩阵(给的形式是字符串数组),从矩阵中删除一些列,可以使得剩下的矩阵的每一行,都是按照字母序排好顺序的,问最少删除多少列。
解题思路:
题目中问的是最少删除多少列,反过来理解就是最多能剩多少列,而且这些列必须是“递增”的,这里的“递增”指的是在剩余矩阵的每一行都是递增,行与行之间没有关系。
这里我们可以联想到最长递增子序列,只要将“递增”的含义和形式变化一下,这道题目就可以使用最长递增子序列的求解方法来做。
具体的方法是,使用dp[i]表示以第i列结尾的最长递增子序列的长度,那么递推公式就是:
dp[i + 1] = max{ dp[j] | 0 < j < i } + 1
在计算出以每一行结尾的最长递增子序列之后,在所有情况中找到一个最长的,用矩阵的总的列数减去最长递增子序列的长度,就是最少删除的列数。
class Solution {
public boolean judge(char[] a, char[] b){
int len = a.length;
for(int i = 0; i < len; i++)
if(a[i] > b[i]) {
return false;
}
return true;
}
public int minDeletionSize(String[] A) {
int row = A[0].length(), col = A.length;
char[][] temp = new char[col][];
for(int i = 0; i < col; i++)
temp[i] = A[i].toCharArray();
char[][] chs = new char[row][col];
for(int i = 0; i < row; i++){
for(int j = 0; j < col; j++){
chs[i][j] = temp[j][i];
}
}
int[] record = new int[row];
for(int i = 0; i < row; i++){
int cur = 0;
for(int j = 0; j < i; j++){
if(judge(chs[j], chs[i])){
cur = Math.max(cur, record[j]);
}
}
record[i] = cur + 1;
}
int max = 0;
for(int num : record)
max = Math.max(max, num);
return row - max;
}
}