上班无事,刷力扣发现了个新名词:单调栈
题目:496. 下一个更大元素 I
概念
名字上就听的出来,单调栈中存放的数据应该是有序的,所以单调栈也分为单调递增栈和单调递减栈
单调递增栈:栈中数据出栈的序列为单调递增序列
单调递减栈:栈中数据出栈的序列为单调递减序列
ps:这里一定要注意所说的递增递减指的是出栈的顺序,而不是在栈中数据的顺序
实例
现在有一组数10,3,7,4,12。从左到右依次入栈,则如果栈为空或入栈元素值小于栈顶元素值,则入栈;否则,如果入栈则会破坏栈的单调性,则需要把比入栈元素小的元素全部出栈。单调递减的栈反之。
10入栈时,栈为空,直接入栈,栈内元素为10。
3入栈时,栈顶元素10比3大,则入栈,栈内元素为10,3。
7入栈时,栈顶元素3比7小,则栈顶元素出栈,此时栈顶元素为10,比7大,则7入栈,栈内元素为10,7。
4入栈时,栈顶元素7比4大,则入栈,栈内元素为10,7,4。
12入栈时,栈顶元素4比12小,4出栈,此时栈顶元素为7,仍比12小,栈顶元素7继续出栈,此时栈顶元素为10,仍比12小,10出栈,此时栈为空,12入栈,栈内元素为12。
题目代码
var nextGreaterElement = function (nums1, nums2) {
let map = new Map()
let stack = []
let p = 0
while (p < nums2.length) {
let num = nums2[p]
if (stack.length) {
while (stack[stack.length - 1] < num) {
map.set(stack.pop(), num)
}
}
stack.push(num)
p++
}
while (stack.length) {
map.set(stack.pop(), -1)
}
return nums1.map(num => map.get(num))
};
代码本质上和写两层for循环没啥区别,但是个人觉得可读性更高,多层for循环嵌套加上n个if判断的代码看起来贼蛋疼,另外附上双层for循环版
var nextGreaterElement = function (nums1, nums2) {
let result = []
nums1.forEach(num => {
let index = nums2.indexOf(num)
for (let i = index + 1; i < nums2.length; i++) {
if (nums2[i] > num) {
result.push(nums2[i])
return
}
}
result.push(-1)
})
return result
};