所用代码 java
每日温度 LeetCode 739
题目链接:每日温度 LeetCode 739 - 中等
思路
无。
单调栈:通常是为了找到任一个元素的右边或者左边第一个比自己大或者小的元素的位置,本质是空间换时间
单调栈(递增或递减):记录遍历过的元素,然后两个元素才能做对比
我们存入元素的下标,便可以通过下标找到元素和距离
如果当前遍历的元素大于栈顶元素,就表示栈顶元素右边的最大元素为当前遍历的元素。
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
// java通常用Deque接口来实现栈
Deque<Integer> stack = new LinkedList<>();
int[] result = new int[temperatures.length];
// 先把第一个元素的下标存入栈
stack.push(0);
for (int i = 1; i < temperatures.length; i++) {
// 比较当前元素与栈顶元素的大小
// 若当前元素比栈顶元素小或等就压入栈,使栈保持递增状态(栈顶到栈底)
if (temperatures[i] <= temperatures[stack.peek()]){
stack.push(i);
}else {
// 当前元素比栈顶元素大的时候,就是右边第一个大的元素
while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]){
// 存入结果,栈顶元素就是需操作的下标
result[stack.peek()] = i - stack.peek();
stack.pop();
}
stack.push(i);
}
}
return result;
}
}
写法还可以化简,只需要找到第一个比栈顶元素大的时候才进行poll操作,其他都是push,最后留在栈里面的元素一定使递增的元素,即他们后面的元素都比自己小。
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
// java通常用Deque接口来实现栈
Deque<Integer> stack = new LinkedList<>();
int[] result = new int[temperatures.length];
// 先把第一个元素的下标存入栈
stack.push(0);
for (int i = 1; i < temperatures.length; i++) {
// 只有下一个元素大于栈顶元素的时候才进行操作
while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]){
result[stack.peek()] = i - stack.peek();
stack.pop();
}
stack.push(i);
}
return result;
}
}
总结
单调栈的第一个题,就和之前有一个单调队列的题类似,单调队列我们也是让队列里面排好序,然后
再根据这个次序进行操作。
下一个更大元素 I LeetCode 496
题目链接:下一个更大元素 I - 简单
思路
单调栈实现。
相当于找nums2里面某个元素的右边第一个比它大的数。
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
Deque<Integer> stack = new LinkedList<>();
int[] result = new int[nums1.length];
// 默认没有比它大的元素,所以值为-1
Arrays.fill(result,-1);
// 将nums1的元素存入map,做一个映射关系
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums1.length; i++) {
map.put(nums1[i], i);
}
// 利用nums2生成单调递增的栈
stack.push(0);
for (int i = 1; i < nums2.length; i++) {
// 小于栈顶元素就直接压入
if (nums2[i] <= nums2[stack.peek()]){
stack.push(i);
}else {
while (!stack.isEmpty() && nums2[i] > nums2[stack.peek()]){
// 大于时判断栈顶元素是不是在栈里面
if (map.containsKey(nums2[stack.peek()])){
int index = map.get(nums2[stack.peek()]);
result[index] = nums2[i];
}
stack.pop();
}
stack.push(i);
}
}
return result;
}
}
总结
单调递增栈(栈顶到栈底)求的是右边第一个比他大的元素,递减是找第一个比他小的元素