【单调栈】
单调栈:顾名思义,就是这个栈是单调的,后面也会运用这一点
模版:
var nextGreater = function (nums) {
let n = nums.length
let res = new Array() // 结果数组
let stack = new Array() // 栈数组
for(let i=n-1; i>=0; i--) {
// 保证了这个栈数组一定是一个降序的数组
// 经过这一步 保证了栈顶元素 要不比当前元素大 要不栈为空
while(stack.length!==0 && stack[stack.length-1]<=nums[i])
stack.pop()
res[i] = stack.length===0 ? -1 : stack[stack.length-1]
// 这里很聪明 一定要先赋值结果数组 再让当前元素入栈
// 这里保证了每个元素 必入栈
stack.push(nums[i])
}
return res
}
一、下一个更大元素:
LeetCode496
链接:
题目:
思路:
这道题就是多了个nums1数组来迷惑你,其实跟模版是一样的
我们的思路就是找出nums2的结果数组,然后把nums1的每个数找到nums2的对应下标,从而在得出的结果数组中找出对应的数,重新组成一个数组
代码:
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number[]}
*/
var nextGreaterElement = function(nums1, nums2) {
let res = nextGreater(nums2)
let result = new Array()
for(let c of nums1) {
result.push(res[nums2.indexOf(c)])
}
return result
};
var nextGreater = function (nums) {
let n = nums.length
let res = new Array() // 结果数组
let stack = new Array() // 栈数组
for(let i=n-1; i>=0; i--) {
// 保证了这个栈数组一定是一个降序的数组
// 经过这一步 保证了栈顶元素 要不比当前元素大 要不栈为空
while(stack.length!==0 && stack[stack.length-1]<=nums[i])
stack.pop()
res[i] = stack.length===0 ? -1 : stack[stack.length-1]
// 这里很聪明 一定要先赋值结果数组 再让当前元素入栈
// 这里保证了每个元素 必入栈
stack.push(nums[i])
}
return res
}
二、下一个更大元素的下标
LeetCode739
链接:
题目:
思路:
这道题也是把模版稍微改动一下就行
模版要的是下一个更大的元素
这里要的是下一个更大的元素的下标,所以只要把模版里的stack用来存储下一个更大元素的下标就行了
代码:
/**
* @param {number[]} temperatures
* @return {number[]}
*/
var dailyTemperatures = function(temperatures) {
let n = temperatures.length
// 加个n稍微快点 内存消耗稍微小点
let res = new Array(n)
let stack = new Array()
for(let i=n-1; i>=0; i--) {
while(stack.length!==0 && temperatures[stack[stack.length-1]]<=temperatures[i])
stack.pop()
res[i] = stack.length===0 ? 0 : stack[stack.length-1]-i
stack.push(i)
}
return res
};
三、循环数组中找下一个更大元素
LeetCode503
链接:
题目:
思路:
这道题还是可以运用模版,很容易就能想到,只要在原数组后再补一段同样数组就行,也就是数组长度翻倍
代码:
/**
* @param {number[]} nums
* @return {number[]}
*/
var nextGreaterElements = function(nums) {
let n = nums.length
let res = new Array(n)
let stack = new Array()
for(let i=2*n-1; i>=0; i--) {
while(stack.length!==0 && stack[stack.length-1]<=nums[i%n])
stack.pop()
// res[i] = stack.length===0 ? -1 : stack[stack.length-1]
// 这样写也是可以的 因为本身就是从后往前 前面的结果也会覆盖住之前的值
// 所以这里取余 或者是返回前n个值都是可以的
res[i%n] = stack.length===0 ? -1 : stack[stack.length-1]
stack.push(nums[i%n])
}
// return res.slice(0, n)
return res
};
截取数组前n个元素(左闭右开)
arr.slice(0, n)
写在最后:
栈 可以啊