关键点
使用条件:一维数组,想要寻找任一个元素的右边或者左边比第一个自己大或小的元素的位置;
原理:空间换时间,遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素;
维护单调栈:如果要找右边比自己大的,需要维护一个单调递增的单调栈; 比自己小的,则相反
739.每日温度
题目链接: 力扣题目链接(opens new window)
这里为了提现三个条件,写的比较复杂
1) 如果当前遍历的温度比栈顶 元素小,则加入栈
2)如果等于,则加入栈
3)如果大于栈顶的元素,则弹出栈顶元素,然后可以计算出这个栈顶元素在多少个之后比它大的值,是当前元素坐标 - 栈顶元素,如果弹出后还有比栈顶元素大的,则继续计算
function dailyTemperatures(temperatures) {let result = new Array(temperatures.length).fill(0)let stack = []stack.push(0)for(let i = 1; i < temperatures.length; i = i + 1) {let top = stack[stack.length - 1]if(temperatures[i] < temperatures[top]) {stack.push(i)} else if(temperatures[i] === temperatures[top]) {stack.push(i)} else {while(stack.length && temperatures[i] > temperatures[stack[stack.length - 1]]) {top = stack.pop()result[top] = i - top}stack.push(i)}}return result
}
496.下一个更大元素 I
题目链接:. - 力扣(LeetCode)
思路分析:这里是得到:nums1
中数字 x
的 下一个更大元素 是指 x
在 nums2
中对应位置 右侧 的 第一个 比 x
大的元素。
1)先用 map 和单调栈得到 num2中每个元素右边第一个比它大的元素
2)再用 num1去得到每个值对应的值
let reMap = {};let stack = [];let restul = [];for (let k = 0; k < nums2.length; k = k + 1) {reMap[nums2[k]] = -1;}stack.push(0);for (let i = 1; i < nums2.length; i = i + 1) {while (stack.length && nums2[i] > nums2[stack[stack.length - 1]] ) {let top = stack.pop();
// 弹出的元素对应的当前第一个比它大的元素reMap[nums2[top]] = nums2[i];}stack.push(i);}for (let j = 0; j < nums1.length; j = j + 1) {restul[j] = reMap[nums1[j]];}return restul;
503.下一个更大元素II
题目链接: . - 力扣(LeetCode)
思路:把这个数组拼接成回转寿司的形式,然后去求相对应的弹出的 top 的数值,同样是利用单调栈的公式
var nextGreaterElements = function (nums) {const huizhuan = [...nums, ...nums];let result = new Array(nums.length).fill(-1),stack = [];stack.push(0);for (let i = 1; i < huizhuan.length; i = i + 1) {while (stack.length && huizhuan[i] > huizhuan[stack[stack.length - 1]]) {top = stack.pop();result[top] = huizhuan[i];}stack.push(i);}return result.slice(0, nums.length);
};