LeetCode 316. 去除重复字母 栈 哈希
地址 https://leetcode-cn.com/problems/remove-duplicate-letters/
给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。 需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。 注意:该题与 1081 https://leetcode-cn.com/problems/smallest-subsequence-of-distinct-characters 相同 示例 1: 输入:s = "bcabc" 输出:"abc" 示例 2: 输入:s = "cbacdcbc" 输出:"acdb" 提示: 1 <= s.length <= 104 s 由小写英文字母组成
算法1
单调栈和哈希
我们首先需要记录字母在字符串中的出现次数,首选哈希
然后只出现一次的的字母肯定是不能去除的,但是出现多次的字母 如何做取舍? 使用什么数据结构?
使用栈的话,当前字母和栈顶字母进行比较,如果栈顶字母在字符串中出现多次且字母序比当前的字母的大,那么就出栈。
由于每个字母只需要选择一次,已经在栈中的字母不必进行上述比较。
如图
记录字母出现的次数 和字母是否已经存在栈中适应哈希
使用单调栈 排序可能的 字母序比较小的选择
C++ 代码
class Solution { public: int mm[26]; stack<char> st; int isInSt[26]; string removeDuplicateLetters(string s) { for (int i = 0; i < s.size(); i++) { mm[s[i]-'a']++; } for (int i = 0; i < s.size(); i++) { if(isInSt[s[i]-'a'] ==0){ while (!st.empty()&& isInSt[s[i]-'a'] == 0) { char top = st.top(); if (mm[top-'a'] > 1 && s[i]< top ) { st.pop(); mm[top-'a']--; isInSt[top-'a']--; } else { break; } } //无论如何 此刻总要push进去的 st.push(s[i]); isInSt[s[i]-'a']++; } else { mm[s[i]-'a']--; } } string ans = ""; while (!st.empty()) { ans.insert(ans.begin(), st.top()); st.pop(); } return ans; } };
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
![阿里打赏](https://files.cnblogs.com/files/itdef/ali2.bmp)
![微信打赏](https://files.cnblogs.com/files/itdef/weixin2.bmp)