【棧】B018_LC_不同字符的最小子序列(單調遞增棧 + 貪心)

一、Problem

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

Input: "cdadabcc"
Output: "adbc"

Constraints:

1 <= text.length <= 1000
text consists of lowercase English letters.

二、Solution

方法一:棧

思路

本題關鍵:結果字符串要包含 text 的每一種字符,且字典序在 text 中是最小

我們希望得到的序列儘量呈升序結構,換句話說就是儘量讓 text 中字典序較小的出現在前面,因爲這樣形成的序列就是最小的,但如果字典序較小的字符 c1 在字典序較大字符 c2 的位置的後面,那麼我們要不要通過刪除 c2 從而維護這個字典序最小的序列呢?這取決於 c1 的後面還有沒有 c2 這種字符:

  • 如果有,我們大膽刪 c2
  • 否則,我們選擇需保留 c2

所以我們可維護一個單調遞增的棧,如果棧頂元素(當前位置之前字典序最大的字符)大於當前字符 c1,那麼按照上面的思路進行刪除/保留…

class Solution {
    public String smallestSubsequence(String text) {
        char[] s = text.toCharArray();
        Stack<Character> st = new Stack<>();

        for (int i = 0; i < s.length; i++) {
            if (st.contains(s[i]))
                continue;
            while (!st.isEmpty() && st.peek() > s[i] && text.indexOf(st.peek(), i) != -1)
                st.pop();
            st.push(s[i]);
        }
        StringBuilder ans = new StringBuilder();
        while (!st.isEmpty()) 
            ans.insert(0, st.pop());
        return ans.toString();
    }
}
複雜度分析
  • 時間複雜度:O(n2)O(n^2)
  • 空間複雜度:O(n)O(n)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章