【LeetCode316】去除重复字母(单调栈+哈希)

简介: 先读懂题意,删除重复的字母,得到最小的字符串。如babc,删除重复字母有两种结果bac,abc。abc小于bac,所以答案是abc。遇到一个新字符 如果比栈顶小 并且在新字符后面还有和栈顶一样的 就把栈顶的字符抛弃了。

一、题目

image.png

二、思路

先读懂题意,删除重复的字母,得到最小的字符串。如babc,删除重复字母有两种结果bac,abc。abc小于bac,所以答案是abc。


遇到一个新字符 如果比栈顶小 并且在新字符后面还有和栈顶一样的 就把栈顶的字符抛弃了。


(1)前者的条件即单调栈的步骤(for中带while);可以用哈希表inst统计当前字符是否在栈中。

(2)为了满足后者的条件,即如果栈顶元素大于当前遍历到的字符s[i],并且栈顶元素在后面还存在,所以可以放心的pop掉。可以用哈希表cnt统计s中剩余字符的出现次数。

(3)上面的循环操作后,得到最后的栈,把栈底到栈顶元素串成字符串。

image.png



三、代码

class Solution {
public:
    string removeDuplicateLetters(string s) {
        stack<char> st;
        //剩余字符出现次数的哈希表
        unordered_map<char, int> cnt;
        //当前字符是否存在栈中
        unordered_map<char, bool> inst;
        for(auto& c: s){
            ++cnt[c];
        }
        for(int i= 0; i < s.size(); i++){
            char c = s[i];
            //当前字符已经在栈中则跳出循环
            if(inst[c]){
                --cnt[c];
                continue;
            }
            //栈顶元素大于当前字符,并且栈顶元素在后面还存在,所以可以pop
            while(!st.empty() && st.top() > c && cnt[st.top()] > 0){
                inst[st.top()] = false;
                st.pop();
            }
            st.push(c);
            --cnt[c];
            //当前c字符存在栈中
            inst[c] = true;
        }
        string res;
        //把栈底到栈顶元素串成字符串
        while(!st.empty()){
            res = st.top() + res;
            st.pop();
        }
        return res;
    }
};
相关文章
|
4月前
|
存储 算法
LeetCode第49题字母异位词分组
LeetCode第49题"字母异位词分组"的解题方法,通过将每个字符串的字符排序后作为键存储在HashMap中,有效地将所有字母异位词分组。
LeetCode第49题字母异位词分组
|
2月前
|
存储
Leetcode第49题(字母异位词分组)
LeetCode第49题要求将字符串数组中的字母异位词分组,可以通过将每个字符串排序后作为键存入哈希表,最后将哈希表中的值添加到结果列表中来实现。
16 1
|
2月前
|
算法
Leetcode第十七题(电话号码的字母组合)
这篇文章介绍了如何使用深度优先搜索(DFS)算法来解决LeetCode第17题——电话号码的字母组合问题,通过递归方法生成所有可能的字母组合。
21 0
Leetcode第十七题(电话号码的字母组合)
|
2月前
|
索引
【LeetCode 11】242.有效的字母异位词
【LeetCode 11】242.有效的字母异位词
17 0
【LeetCode 11】242.有效的字母异位词
|
2月前
|
算法
【LeetCode 52】17.电话号码的字母组合
【LeetCode 52】17.电话号码的字母组合
34 0
|
2月前
【LeetCode 24】225.用队列实现栈
【LeetCode 24】225.用队列实现栈
12 0
|
2月前
|
算法
【LeetCode 23】232.用栈实现队列
【LeetCode 23】232.用栈实现队列
21 0
|
4月前
|
算法
LeetCode第17题电话号码的字母组合
该文章介绍了 LeetCode 第 17 题电话号码的字母组合的解法,通过分析得出可使用递归和回溯的思想解决,避免循环穷举的高循环次数,并给出了具体的编码实现,同时总结了该题较难理解,需要了解递归的本质,当嵌套循环层次多时可考虑递归。
LeetCode第17题电话号码的字母组合
|
4月前
|
Python
【Leetcode刷题Python】946. 验证栈序列
LeetCode题目“946. 验证栈序列”的Python解决方案,通过模拟栈的压入和弹出操作来验证给定的两个序列是否能通过合法的栈操作得到。
32 6
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 30. 包含min函数的栈
本文提供了实现一个包含min函数的栈的Python代码,确保min、push和pop操作的时间复杂度为O(1)。
29 4