1. 程式人生 > 其它 >去除重複字母(單調棧/LeetCode)

去除重複字母(單調棧/LeetCode)

技術標籤:leetcode

題目連結

題目描述

給你一個字串 s ,請你去除字串中重複的字母,使得每個字母只出現一次。需保證 返回結果的字典序最小(要求不能打亂其他字元的相對位置)。

示例 1:

輸入:s = "bcabc"
輸出:"abc"

示例 2:

輸入:s = "cbacdcbc"
輸出:"acdb"

提示:

1 <= s.length <= 104
s 由小寫英文字母組成

思路

以輸入:s = “bcabc” 輸出:"abc"為例給出棧的變化過程:

       c比b大         a比c小             a比b小    
                     c後面還有           b後面還有         b比a大             c比b大      c
		->       c      ->               ->               ->         b       ->       b
b                b                 b               a                 a                a

因此需要記錄某個字母是否在棧中,以及某個字母后面還能出現多少次。

程式碼如下:

class Solution {
public:
    string removeDuplicateLetters(string s) {
        vector<bool> visit(26,false);//記錄某個字母是否在棧中
        unordered_map<char,int> counts;//記錄字母出現次數
        stack<char> ss;
        for(auto c:s)
            counts[c]++;
        for
(auto c:s){ counts[c]--; if(ss.empty()){ ss.push(c); visit[c-'a']=true; } //當前元素c比棧頂小,而且棧頂元素後面還能出現,並且當前元素c沒在棧中出現過 while(!ss.empty()&&c<ss.top()&&counts[ss.top()]>0&&!visit[c-'a']){ visit[
ss.top()-'a']=false; ss.pop(); } if(!visit[c-'a']){ ss.push(c); visit[c-'a']=true; } } string ans; while(!ss.empty()){ ans=ss.top()+ans; ss.pop(); } return ans; } };