316. 去除重复字母

贪心+单调栈

贪心:每次栈中总是以最小的字母在前,大的字母在后,如果不满足的出栈调整

1.栈为空入栈  

2.如果栈不为空时:栈中是否有该元素,如果有则不入栈,如果没有则查看该元素与栈顶元素的大小,如果大于栈顶元素,则入栈,如果小于栈顶元素,则循环判断(后续是否该有栈顶元素,如果有则出栈)

class Solution {
public:
/*1.栈为空入栈  2.如果栈不为空时:栈中是否有该元素,如果有则不入栈,如果没有则查看该元素与栈顶元素的大小,如果大于栈顶元素,则入栈,如果小于栈顶元素,则循环判断(后续是否该有栈顶元素,如果有则出栈)*/
    string removeDuplicateLetters(string s) {
        // 字符串长度
        int len = s.size();
        // 记录每个字符最后出现的下标
        vector<int> record(26,0);
        for(int i=0;i<len;i++){
            record[s[i] - 'a'] = i;
        }
        // PrintVector(record);
        // 记录每个字符在栈中是否已经出现了
        vector<bool> present(26,false);
        // 遍历整个字符串
        string result;
        for(int i=0;i<len;i++){
            // 栈为空时入栈
            if(result.size()==0){
                result.push_back(s[i]);
                present[s[i]-'a'] = true;
            }else{
                // 栈不为空时:判断栈中是否有该元素
                if(present[s[i]-'a']){
                    continue;
                }else{
                    // 没有时查看当前元素与栈顶元素的大小,当前元素大于栈顶元素,直接入栈
                    if(s[i]>result.back()){
                        result.push_back(s[i]);
                        present[s[i]-'a'] = true;
                    }else{
                        // 如果小于栈顶元素,则查看后续串中是否还有栈顶元素,如果有栈顶元素出栈,并将当前元素加入栈中
                        while(!result.empty()&&result.back()>s[i]&&i<record[result.back()-'a']){
                            present[result.back()-'a'] = false;
                            result.pop_back();
                        }
                        result.push_back(s[i]);
                        present[s[i]-'a'] = true;
                    }
                }
            }
        }
        return result;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值