# 955. Delete Columns to Make Sorted II

**<font color=red>难度: Medium</font>**

## 刷题内容

> 原题连接

* https://leetcode.com/problems/delete-columns-to-make-sorted-ii/

> 内容描述

```
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 = ["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 D such that after deletions, the final array has its elements in lexicographic order (A[0] <= A[1] <= A[2] ... <= A[A.length - 1]).

Return the minimum possible value of D.length.

 

Example 1:

Input: ["ca","bb","ac"]
Output: 1
Explanation: 
After deleting the first column, A = ["a", "b", "c"].
Now A is in lexicographic order (ie. A[0] <= A[1] <= A[2]).
We require at least 1 deletion since initially A was not in lexicographic order, so the answer is 1.
Example 2:

Input: ["xc","yb","za"]
Output: 0
Explanation: 
A is already in lexicographic order, so we don't need to delete anything.
Note that the rows of A are not necessarily in lexicographic order:
ie. it is NOT necessarily true that (A[0][0] <= A[0][1] <= ...)
Example 3:

Input: ["zyx","wvu","tsr"]
Output: 3
Explanation: 
We have to delete every column.
 

Note:

1 <= A.length <= 100
1 <= A[i].length <= 100
```

## 解题方案

> 思路 1
******- 时间复杂度: O(NlgN * M^2)******- 空间复杂度: O(1)******



还是贪心，参考[lee215](https://leetcode.com/problems/delete-columns-to-make-sorted-ii/discuss/203182/Python-Greedy-Solution)


```python
 
class Solution:
    def minDeletionSize(self, A):
        """
        :type A: List[str]
        :rtype: int
        """
        res, cur = 0, [''] * len(A)
        for col in zip(*A):
            cur2 = list(zip(cur, col))
            if cur2 == sorted(cur2):
                cur = cur2
            else:
                res += 1
        return res
```


> 思路 2
******- 时间复杂度: O(N * M)******- 空间复杂度: O(1)******

首先我们把整个A看成一个矩阵

```
比如这个样子

[‘ca',
 'bb',
 'ac']
```
 



我们一列一列开始比较，从第一列开始比较，固定列的坐标，从上到下比较每一行是否严格符合 lexicographic order 的要求了，
如果某一行已经严格符合 lexicographic order 的要求了，就把对应行记录一下，
后面比较新的一列的时候如果碰到一行不符合要求的，我们就看看这行之前是否已经严格符合要求了，如果没有我们才会选择删除这一列，
因为对于这一行，前面的列并不能给出结果，也就是说要比较到这一列才知道结果，但是这一列不符合要求，所以需要删除这一列

比赛的时候我是这个思路，但是一直有bug，参考[lee215](https://leetcode.com/problems/delete-columns-to-make-sorted-ii/discuss/203182/Python-Greedy-Solution)

beats 100%

```python
class Solution:
    def minDeletionSize(self, A):
        """
        :type A: List[str]
        :rtype: int
        """
        res = 0
        strict_row = set()
        for i in range(len(A[0])):
            flag = True
            cur_strict_row = set(i for i in strict_row)
            for j in range(1, len(A)):
                if A[j][i] < A[j-1][i] and j-1 not in strict_row: # 只要j-1行之前没有严格符合要求，我们都得删除这一列
                    res += 1
                    flag = False
                    break
                if A[j][i] > A[j-1][i]:   # 严格符合要求的行都记录下来，后面就不需要比较了
                    cur_strict_row.add(j-1)
            # 只有当前这一列的所有行都符合要求(不一定严格)，才更新strict_row
            # 因为如果这一列有不符合的，我们就会选择删除这一列了，那么还要沿用之前的列的才更新strict_row
            if flag: 
                strict_row = cur_strict_row
        return res
```



搞一个python的for-else语法糖




```python
class Solution:
    def minDeletionSize(self, A):
        """
        :type A: List[str]
        :rtype: int
        """
        res = 0
        strict_row = set()
        for i in range(len(A[0])):
            cur_strict_row = set(i for i in strict_row)
            for j in range(1, len(A)):
                if A[j][i] < A[j-1][i] and j-1 not in strict_row: # 只要j-1行之前没有严格符合要求，我们都得删除这一列
                    res += 1
                    break
                if A[j][i] > A[j-1][i]:   # 严格符合要求的行都记录下来，后面就不需要比较了
                    cur_strict_row.add(j-1)
            # 只有当前这一列的所有行都符合要求(不一定严格)，才更新strict_row
            # 因为如果这一列有不符合的，我们就会选择删除这一列了，那么还要沿用之前的列的才更新strict_row
            else: 
                strict_row = cur_strict_row
        return res
```
