【栈】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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章