316、去除重复字母remove duplicate letters

不能打乱相对顺序要按字典序
输入adbcd : 输出abcd

//单调栈
class Solution {
    public String removeDuplicateLetters(String s) {
        int len = s.length();
        //1.特判
        if(len < 2) return s;
 
        //2.1用于判断字符是否已经出现过
        boolean[] flag = new boolean[26];
        //2.2字符后续时会出现
        int[] nums = new int[26];
         for(int i=0;i<len;i++)
            nums[arrChar[i]-'a'] = i;
        //2.3使用deque来做单调栈并存入哨兵a就无需判断栈是否为空
        ArrayDeque<Character> deque = new ArrayDeque();
        deque.add('a');
        //2.4字符串转数组,因为charAt会判断字符串是否越界
        char[] arrChar = s.toCharArray();
       
        
        for(int i=0;i<len;i++)
        {
            char curChar = arrChar[i];
            //3.1出现就跳过本次
            if(flag[curChar-'a'])
                continue;
            //3.2当前小于之前并且之前的还会出现就弹出之前
            while(curChar<deque.peekLast() && nums[deque.peekLast()-'a']>i)
            {
                char top = deque.pollLast();
                flag[top-'a'] = false;
            }
            //3.3加入
            deque.addLast(curChar);
            flag[curChar-'a']=true;
        }
 
        //4,1删除哨兵
        deque.pollFirst();
        StringBuilder sb = new StringBuilder();
        //4.2取出元素
        while(!deque.isEmpty())
            sb.append(deque.pollFirst());
        return sb.toString();
    }
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值