【算法训练】单调栈相关

前一篇文章中接触了单调栈的问题,今天的题目中也采用了单调栈相关技巧 去除字符串中的重复字符

一、去除重复字母316

在这里插入图片描述

1、分析

题目有三个要求
(1)首先要保证每个字母出现的相对顺序和原数组中相同——单调栈保证顺序
(2)然后就要求每个字母在结果中只出现一次——严格控制出现次数
(3)还要保证返回结果的字典序最小——即要保证字典序小的字符要在前面;可以考虑将栈中大于当前元素的内容出栈,然后将当前元素入栈。但是在出栈操作前,还要考虑到每个元素都要出现一次这点,所以就看栈顶元素在后续是否还有出现机会(这里我们可以采用字典去保存字符串中的所有元素总共的数量,每当遍历到一次就将该字符对应的总数减一)
具体见代码和注释

2、代码

class Solution:
    def smallestSubsequence(self, s: str) -> str:
        count = Counter(s) #用于记录每个元素的个数
        stack = []
        for c in s:
            count[c] -= 1
            if c in stack: #保证每个元素不重复出现
                continue
            while stack and stack[-1]>=c: #利用单调栈,保证原来数组中的次序,并保证最终结果的字典序
                if count[stack[-1]]==0: #防止丢失元素,若栈顶元素在后面不再出现,那么不能出栈
                    break
                stack.pop()
            stack.append(c)
        return ''.join(stack) #将数组转变为字符串形式

JS

/**
 * @param {string} s
 * @return {string}
 */
var smallestSubsequence = function(s) {
    let stack = [],count = {};
    for(let c of s){
        if(c in count){
            count[c] += 1;
        }else{
            count[c] = 1;
        }
    }
    for(let c of s){
        count[c] -= 1;
        if(stack.includes(c)){
            continue;
        }
        while(stack.length!=0 && stack[stack.length-1]>=c){
            if(count[stack[stack.length-1]]==0){
                break;
            }
            stack.pop();
        }
        stack.push(c);
    }
    return stack.join('')

};

二、不同字符的最小子序列 1081

在这里插入图片描述
与上一题完全一样。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值