单调栈总结

一、单调栈

1.单调栈中存放的数据是有序的

单调递增栈:从栈顶到栈底单调第增;
单调递减栈:从栈顶到栈底单调第减。

2.声明单调栈
Deque<E> stack = new ArrayDeque<>();

Deque是Queue的子接口,我们知道Queue是一种队列形式,而Deque则是双向队列,它支持从两个端点方向检索和插入元素,因此Deque既可以支持LIFO形式也可以支持LIFO形式.Deque接口是一种比Stack和Vector更为丰富的抽象数据形式,因为它同时实现了以上两者.
常用方法:
插入元素
1.push(E),向队列头部插入元素
2.addFirst(E),向队列头部插入元素
3.addFirst(E),向队列尾部插入元素
获取元素
4.peekFirst(),获取队列头部元素
5.peekLast(),获取队列尾部元素
弹出元素
6.pop(),弹出队列头部元素
7.removeFirst(),弹出队列头部元素
8.removeLast(),弹出队列尾部元素

3.如何实现单调栈

实现单调递减栈(栈为空或者栈顶元素比入栈元素小时才可入栈):设有一组数据2,1,5,6,2,3,从左往右依次入栈:
1)2入栈时,栈为空,可直接入栈;
2)1准备入栈,由于栈顶元素2大于1,所以2出栈,1入栈;
3)5准备入栈,由于栈顶元素1小于5,则5入栈,此时栈内元素有1,5;
4)6准备入栈,5<6,则6入栈,此时栈内元素有1,5,6;
5)2准备入栈,6>2,则6出栈;5>2,则5也出栈;1<2,则2入栈;
6)3准备入栈,2<3,则3入栈,此时栈内元素有1,2,3,栈顶为3,栈底为1。
伪代码(Java)

//设待入栈的数组为nums
Deque<Integer> st = new ArrayDeque<>();//定义一个栈,实质为双边队列,从尾部入栈,出栈的时候程序从顶部取元素出栈
int len = 数组长度;
int index = 0;
while(index<len){
	while(index<len && (栈空||栈顶元素小于等于等待入栈元素){
		st.addLast(nums[index++]);//入栈;
	}
	if(index = len)
		break;
	while(栈非空 && 栈顶元素大于等待入栈元素 && st.size()+len-index-1>=最后要保留的数组长度){
			st.removeLast();//栈顶元素出栈;
		}
		st.addLast(nums[index++]);//等待入栈元素入栈;
	}
	//从栈顶取排好序的元素出来
	用st.pollFirst();或st.removeFirst();
}

二、例题讲解

LeetCode 402题
请添加图片描述
解题思路:
1.先考虑用单调增还是单调减栈
这里要求移除k个元素后得到的最终结果值最小,则左边的数肯定是越小越好,所以用单调递增栈,保证最后结果开头数字最小;
2.注意什么时候停止,由于最后要保留num.length-k个数字,所以要确保有足够的数。

class Solution {
    public String removeKdigits(String num, int k) {
        Deque<Character> st = new ArrayDeque<>();
        int index = 0;
        int len = num.length();
        int count = len-k;
        if(count==0) return "0";
        while(index < len){
            while(index<len&&(st.isEmpty()||st.peekLast()<=num.charAt(index))){
                st.addLast(num.charAt(index++));
            }      
            if(index==len)
                break;
            while(!st.isEmpty() && st.peekLast()>num.charAt(index) && st.size()+len-index-1 >= count){
                st.removeLast();
            }
            st.addLast(num.charAt(index++));
        }
        StringBuilder sb = new StringBuilder();
        while(!st.isEmpty() && st.peekFirst()=='0')
            st.removeFirst();
        if(st.isEmpty())
            return "0";
        index = 0;
        while(!st.isEmpty()&&index < count){//只取st的前count个数
            sb.append(st.removeFirst());
            index++;
        }
        return sb.toString();
    }
}

单调栈的例题在LeetCode上还有316、321、42、84等

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值