单调栈
一、应用场景
通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置。以空间换时间,复杂度为O(n)。
二、思路
(1)单调栈里面放的是元素下标i(比较的时候用num[i]获取)
(2)单调栈里面元素的顺序:求右边第一大时为从栈顶到栈底递增,右边第一小为递减
(3)具体情况:
- 当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况
- 当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况
- 当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况
三、举例
求输入数组元素右边第一大的元素下标。 输入: [1,2,1] 输出: [1,-1,-1]
分析:
- 当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况 --> 为了保持栈是递增顺序,把元素T[i]压入栈
- 当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况 --> 因为求的是右边第一个大于的元素而非大于等于,所以也需要把元素T[i]压入栈
- 当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况 --> 找到第一个大于的元素了,把栈内所有小于该元素的值全都弹出,并记录结果result[stack.top()] = i - stack.top()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | class Solution { public int [] findFirstBig( int [] T) { int lens=T.length; int []res= new int [lens]; /** 如果当前遍历的元素 大于栈顶元素,表示 栈顶元素的 右边的最大的元素就是 当前遍历的元素, 所以弹出 栈顶元素,并记录 如果栈不空的话,还要考虑新的栈顶与当前元素的大小关系 否则的话,可以直接入栈。 注意,单调栈里 加入的元素是 下标。 */ Deque<Integer> stack= new LinkedList<>(); stack.push( 0 ); for ( int i= 1 ;i<lens;i++){ if (T[i]<=T[stack.peek()]){ stack.push(i); } else { while (!stack.isEmpty()&&T[i]>T[stack.peek()]){ res[stack.peek()]=i-stack.peek(); stack.pop(); } stack.push(i); } } return res; } |
参考:代码随想录
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!