本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、题目描述:
955. 删列造序 II - 力扣(LeetCode) (leetcode-cn.com)
给定由 n 个字符串组成的数组 strs,其中每个字符串长度相等。
选取一个删除索引序列,对于 strs 中的每个字符串,删除对应每个索引处的字符。
比如,有 strs = ["abcdef", "uvwxyz"],删除索引序列 {0, 2, 3},删除后 strs 为["bef", "vyz"]。
假设,我们选择了一组删除索引 answer,那么在执行删除操作之后,最终得到的数组的元素是按 字典序(strs[0] <= strs[1] <= strs[2] ... <= strs[n - 1])排列的,然后请你返回 answer.length 的最小可能值。
示例 1:
输入:strs = ["ca","bb","ac"]
输出:1
解释:
删除第一列后,strs = ["a", "b", "c"]。
现在 strs 中元素是按字典排列的 (即,strs[0] <= strs[1] <= strs[2])。
我们至少需要进行 1 次删除,因为最初 strs 不是按字典序排列的,所以答案是 1。
示例 2:
输入:strs = ["xc","yb","za"]
输出:0
解释:
strs 的列已经是按字典序排列了,所以我们不需要删除任何东西。
注意 strs 的行不需要按字典序排列。
也就是说,strs[0][0] <= strs[0][1] <= ... 不一定成立。
示例 3:
输入:strs = ["zyx","wvu","tsr"]
输出:3
解释:
我们必须删掉每一列。
提示:
- n == strs.length
- 1 <= n <= 100
- 1 <= strs[i].length <= 100
- strs[i] 由小写英文字母组成
二、思路分析:
遍历每一列
用pre_ordered[]标记当前数组元素排序状态
对于每一列 先遍历所有数组元素检查是否需要删除该列(出现降序的情况),若需要删除,退出循环继续下一列的比较,pre_ordered没有任何改变
然后还是将数组元素遍历一遍,更新pre_ordered,同时使用boolean ok标记是否可在当前列确定所有数组元素按照字典序排列 ,遍历结束后若ok=true,返回需要删除的最小列数,否则继续下一列的比较
三、AC 代码:
class Solution {
public int minDeletionSize(String[] A) {
boolean TRUE=true,FALSE=false;
int res=0;
boolean[] pre_ordered=new boolean[A.length];
Arrays.fill(pre_ordered,FALSE);
for(int j=0;j<A[0].length();j++){
boolean del=false;
//若必须删除此列 跳出循环继续下一列的比较
for(int i=0;i<A.length-1;i++){
if(!pre_ordered[i]&&A[i].charAt(j)>A[i+1].charAt(j)){
res++;
del=true;
break;
}
}
if(del)
continue;
boolean ok=true;
for(int i=0;i<A.length-1;i++){
//pre_ordered[i]状态更改为1的情况,其他情况下不需要更改pre_ordered[i]
if(A[i].charAt(j)<A[i+1].charAt(j))
pre_ordered[i]=TRUE;
//此列中依然出现相等顺序的情况,ok标记为false
else if(!pre_ordered[i])
ok=false;
}
//所有数组元素已经确定按照字典序,返回要删除的最小列数
if(ok)
return res;
}
return res;
}
}