1、单调栈
- 单调栈的使用场景
- 通常是一维数组,要寻找任意一个元素 的右边或左边 第一个比自己大或者小的元素的位置
- 单调栈的时间复杂度
- O(n)
- 单调栈的原理
- 单调栈的本质:空间换时间
- 因为在遍历过程中需要一个栈来记录右边第一个比当前元素高的元素
- 优点是整个数组只需要遍历一次, 时间复杂度:O(n)
- 更直白来说,就是用一个栈来记录我们遍历过的元素,因为我们遍历数组的时候,我们不知道之前都遍历了哪些元素,以至于遍历一个元素找不到是不是之前遍历过一个更小的,所以我们需要用一个容器(这里用单调栈)来记录我们遍历过的元素。
- 单调栈的本质:空间换时间
- 需明确的问题
- 单调栈里存放的元素是什么?
- 单调栈里只需存放元素下标i即可,如果需要使用对应的元素,直接T[i]就可以获取。
- 单调栈里元素是递增呢? 还是递减呢?
- 单调栈里存放的元素是什么?
2、leetcode739 每日温度
-
本题其实就是找到一个元素右边第一个比自己大的元素,使用单调栈求解
-
具体步骤
-
可以从前往后处理所有的temperatures[i],使用某类容器装载我们所有的「待更新」的位置(下标),假设当前处理到的是 temperatures[i]:
-
若其比容器内的任意位置(下标)对应温度要低,其必然不能更新任何位置(下标),将其也加入容器尾部(此时我们发现,若有一个新的位置(下标)加入容器,其必然是当前所有待更新位置(下标)中的温度最低的,即容器内的温度单调递减);
-
若其价格高于容器内的任一位置(下标)对应温度,其能够更新容器位置(下标)的答案,并且由于我们容器满足单调递减特性,我们必然能够从尾部开始取出待更新位置来进行更新答案,直到处理完成或遇到第一个无法更新位置。
-
-
由于需要往尾部添加和取出元素,因此容器可使用「栈」。
-
-
代码
class Solution { public int[] dailyTemperatures(int[] temperatures) { int[] res = new int[temperatures.length]; Deque<Integer> queue = new ArrayDeque<>(); for(int i=0; i<temperatures.length; i++) { while(!queue.isEmpty() && temperatures[i]>temperatures[queue.peekLast()]) { int index = queue.pollLast(); res[index] = i-index; } queue.addLast(i); } return res; } }
3、leetcode496 下一个更大元素Ⅰ
- 求nums2中的各个元素的右边第一个比自己大的元素,nums1获取相应答案
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
int[] res = new int[nums1.length];
Deque<Integer> dq = new ArrayDeque();
Map<Integer, Integer> map = new HashMap();
for(int num : nums2) {
while(!dq.isEmpty() && dq.peekLast()<num) {
map.put(dq.pollLast(), num);
}
dq.addLast(num);
}
for(int i=0; i<nums1.length; i++) {
res[i] = map.getOrDefault(nums1[i], -1);
}
return res;
}
}
标签:容器,遍历,下标,int,元素,day58,单调
From: https://www.cnblogs.com/hzj-bolg/p/17212867.html