【LeetCode】316. 去除重复字母

316. 去除重复字母

知识点:栈;单调

题目描述

给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。

示例
输入:s = "bcabc" 输出:"abc" 输入:s = "cbacdcbc" 输出:"acdb"

解法一:单调

我们来仔细分析一下这道题目,它结合了很多知识点,因为题目中提出了很多要求。
1.去掉重复的;对于去重最常用的就是set,可以新建一个set往里放元素达到去重的目的;或者可以直接新建一个数组,当我们把元素放到某一容器里时,通过一个标志位来看此元素是否在容器里出现。
2.保证顺序;这个可以用栈来实现,再结合上要求1,那就可以定义一个map,key是字符,value是true或false;只要入栈了那就true,保证后面的一样的元素不会再入栈了。
3.返回的字典序最小;这个要求什么意思,就是说哦比如例1,我们可以返回bca,但是答案应该是abc,因为abc字典序小,这怎么实现呢,我们应该要想到单调栈,比如前面的bc比a要大,在a入栈的时候直接弹走,保证栈是单调递增的。但是这也是有错误的,比如bcab,要是按这样那答案成了ab了,c没了,所以如果a之前栈里的元素在整个数组中只出现了一次,那就不能管单调了,人家都得留下来,就这独苗了。所以说这并不是严格意义上的单调栈。但是也用到了单调栈的思想

class Solution { public String removeDuplicateLetters(String s) { Stack<Character> stack = new Stack<>(); int[] count = new int[256]; //记录每个字符的次数; for(int i = 0; i < s.length(); i++){ count[s.charAt(i)]++; } boolean[] instack = new boolean[256]; //记录是否在栈中,用于去重; for(Character c : s.toCharArray()){ count[c]--; if(instack[c]) continue; //栈里有这个元素,那再来一个就不用管了; while(!stack.isEmpty() && c < stack.peek()){ //维持一个单调递增栈; if(count[stack.peek()] == 0){ break; //独苗不能弹; } instack[stack.pop()] = false; } stack.push(c); instack[c] = true; } StringBuilder sb = new StringBuilder(); while(!stack.isEmpty()){ sb.append(stack.pop()); } return sb.reverse().toString(); } }

体会

这道题目很有意思,用到了很多思想,要做熟彻底弄会。

相关链接

去掉重复字母


__EOF__

本文作者Curryxin
本文链接https://www.cnblogs.com/Curryxin/p/15136975.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Curryxin  阅读(656)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
Live2D
欢迎阅读『【LeetCode】316. 去除重复字母』
点击右上角即可分享
微信分享提示