内容学习自代码随想录
单调栈在java里没有专门的API
它是一个先进后出,后进先出的,单调递增或者递减的栈结构。
用于解决寻找左边或者右边的第一个大于/等于/小于它本身的元素。
如下几个题目
比如每日温度这题
我用双层暴力循环时间复杂度是O(N²),单调栈的话是O(N)
采用策略是
建一个linkedList模拟单调栈
里面存储的是每个元素对应的index
在For循环里 {
int ele = arr【i】;
判断 当前元素,是否小于等于栈顶
如果小于 则加入栈顶
如果大于
我们进入一个循环
在list不为空的情况下,持续以当前元素是否大于栈顶做循环{
弹栈,弹出来的其实是元素的下标,
证明这个下标的元素,直到当前i才遇到比它更大的
用result数组存储起来,result【弹栈的下标】 = i - 弹栈的下标
}
循环结束后,当前的栈顶就大于当前元素ele了
我们继续把i加入栈顶。
}
拥有下一个最大值的元素得到赋值,剩下的元素即没有比它还大的,它们的下标还在栈里。
栈对应OD题目
找最小数
【华为OD机试真题2023B卷 JAVA&JS】找最小数_若博豆的博客-CSDN博客
我们按照如下思路
左边的值一定要比右边的值小或者等于,因为左边的位更重,把低的值放入高位。
即使用一个单调栈,栈顶为最大值,
当当前值大于栈顶元素,我们不要这个值
当前值小于栈顶元素,我们更新单调栈,弹出栈顶元素。
保证栈顶元素>= 栈顶下一个元素。
如果弹栈的次数不满足移除K的次数,我们继续循环剩余次数,弹出栈顶元素。
最后注意开头为0的情况进行拼接。
拼接方式采用从底到顶,加首位0的校验
开头0,后续不为0,不拼接开头
全为0,全不拼接,size = 0
全都不是0 全部拼接。
也是使用单调栈
对应力扣下一个更大元素2
我们同样也需要使用一个单调栈,单调栈里存放索引
做两件事情
先放入初始值0索引
从1开始循环
第一件事
判断当前元素是否大于单调栈的值,
不大于就存放至栈里
大于则进行
循环不断移除比当前值小的元素索引,直至循环结束
同时把循环出的元素取出来
赋值给结果数组
result【取出的索引】 = 赋值给当前元素
循环结束后再把当前最大值索引丢入栈中
循环的时候被弹出来的索引值就意味着当前索引的的下一个更大元素是 ele当前值
而 nums.length*2 和 i%nums.length的操作是保证这个数据可以成环
打印情况是result数组和list情况和当前索引
它是一个环状的遍历,遍历两次,索引全部走了两遍。