LeetCode #955 Delete Columns to Make Sorted II 刪列造序 II 955 Delete Columns to Make Sorted II 刪列造序 II

955 Delete Columns to Make Sorted II 刪列造序 II

Description:
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:

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.

題目描述:
給定由 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] 由小寫英文字母組成

思路:

貪心
用一個數組記錄之前的列的相對大小
比如 'ab' 和 'aa' 第二列需要比較大小
但是 'bz' 和 'ca' 第二列不需要比較大小
遍歷按列遍歷 strs 數組
如果這次不需要比較大小直接跳過
如果出現逆序直接刪除該列, 並增加結果
如果當前行小於下一行, 則記錄下一列這一行不需要比較
如果該列需要刪除數組沿用, 否則更新數組
時間複雜度爲 O(mn), 空間複雜度爲 O(m), m 爲 strs 數組的長度, n 爲 strs 中字符串的長度

代碼:
C++:

class Solution 
{
public:
    int minDeletionSize(vector<string>& strs) 
    {
        int m = strs.size(), n = strs.front().size(), result = 0;
        vector<int> visited(m);
        for(int j = 0; j < n; j++) 
        {
            vector<int> cur(visited);
            bool flag = false;
            for (int i = 1; i < m; i++) 
            {
                if (cur[i]) continue;
                if (strs[i - 1][j] > strs[i][j])
                {
                    flag = true;
                    break;
                }
                else if (strs[i - 1][j] < strs[i][j]) cur[i] = 1;
            }
            if (flag) ++result;
            else visited = cur;
        }
        return result;
    }
};

Java:

class Solution {
    public int minDeletionSize(String[] strs) {
        int m = strs.length, n = strs[0].length(), result = 0, visited[] = new int[m];
        for (int j = 0; j < n; j++) {
            int[] cur = Arrays.copyOf(visited, m);
            boolean flag = false;
            for (int i = 1; i < m; i++) {
                if (cur[i] != 0) continue;
                if (strs[i - 1].charAt(j) > strs[i].charAt(j)) {
                    flag = true;
                    break;
                } else if (strs[i - 1].charAt(j) < strs[i].charAt(j)) cur[i] = 1;
            }
            if (flag) ++result;
            else visited = cur;
        }
        return result;
    }
}

Python:

class Solution:
    def minDeletionSize(self, strs: List[str]) -> int:
        visited, n, result = [False] * (m := len(strs)), len(strs[0]), 0
        for j in range(n):
            flag, cur = False, visited[:]
            for i in range(1, m):
                if cur[i]:
                    continue
                if strs[i - 1][j] > strs[i][j]:
                    flag = True
                    break
                elif strs[i - 1][j] < strs[i][j]:
                    cur[i] = True
            if flag:
                result += 1
            else:
                visited = cur
        return result
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章