[LeetCode] 1081. Smallest Subsequence of Distinct Characters 不同字符的最小子序列



Return the lexicographically smallest subsequence of s that contains all the distinct characters of s exactly once.

Note: This question is the same as 316: https://leetcode.com/problems/remove-duplicate-letters/

Example 1:

Input: s = "bcabc"
Output: "abc"

Example 2:

Input: s = "cbacdcbc"
Output: "acdb"

Constraints:

  • 1 <= s.length <= 1000
  • s consists of lowercase English letters.

這道題跟之前那道 Remove Duplicate Letters 一模一樣,這已經不是第一次遇到這種情況了,博主就納悶了怎么 LeetCode 就沒有個查重系統呢,強行讓我們復習以前做過的題目嗎。這道題讓找出字母順序最小的一個子序列,使得所有的不同的字母只出現一次,之前那道題說的是去掉重復的字母使得每個字母只出現一次,且剩下的是字母順序最小的一個。其實二者說的都是一個東西,這道題實際上需要用單調棧的思路來做,首先需要統計每個字母出現的次數,這里可以使用一個大小為 128 的數組 cnt 來表示,還需要一個數組 visited 來記錄某個字母是否出現過。先遍歷一遍字符串,統計每個字母出現的次數到 cnt 中。再遍歷一遍給定的字符串,對於遍歷到的字母,在 cnt 數組中減去一個,然后看該字母是否已經在 visited 數組中出現過,是的話直接跳過。否則需要進行一個 while 循環,這里的操作實際上是為了確保得到的結果是字母順序最小的,若當前字母小於結果 res 中的最后一個字母,且該最后的字母在 cnt 中還存在,說明之后還會遇到這個字母,則可以在 res 中先去掉這個字母,以保證字母順序最小,並且 visited 數組中標記為0,表示未訪問。這里是盡可能的將 res 打造成單調遞增的,但如果后面沒有這個字母了,就不能移除,所以說並不能保證一定是單調遞增的,但可以保證得到的結果是字母順序最小的。while 循環退出后,將該字母加到結果 res 后,並且 visited 標記為1。這里還有個小 trick,結果 res 在初始化給個0,這樣就不用判空了,而且0是小於所有字母的,不會影響這個邏輯,最后返回的時候去掉首位0就行了,參見代碼如下:


class Solution {
public:
    string smallestSubsequence(string s) {
        string res = "0";
        vector<int> cnt(128), visited(128);
        for (char c : s) ++cnt[c];
        for (char c : s) {
            --cnt[c];
            if (visited[c]) continue;
            while (c < res.back() && cnt[res.back()]) {
                visited[res.back()] = 0;
                res.pop_back();
            }
            res += c;
            visited[c] = 1;
        }
        return res.substr(1);
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/1081


類似題目:

Remove Duplicate Letters


參考資料:

https://leetcode.com/problems/smallest-subsequence-of-distinct-characters/

https://leetcode.com/problems/smallest-subsequence-of-distinct-characters/discuss/308194/C%2B%2B-O(n)-identical-to-316

https://leetcode.com/problems/smallest-subsequence-of-distinct-characters/discuss/308210/JavaC%2B%2BPython-Stack-Solution-O(N)


LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM