【小f的刷题笔记】(JS)单调栈 - 下一个更大元素 LeetCode496 & 下一个更大元素的下标 LeetCode739 & 循环数组中下一个更大元素 LeetCode503

【单调栈】

单调栈:顾名思义,就是这个栈是单调的,后面也会运用这一点

模版:

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

链接:

496.下一个更大元素 I

题目:

在这里插入图片描述

思路:

这道题就是多了个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

链接:

739.每日温度

题目:

在这里插入图片描述

思路:

这道题也是把模版稍微改动一下就行

模版要的是下一个更大的元素

这里要的是下一个更大的元素的下标,所以只要把模版里的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

链接:

503.下一个更大元素 II

题目:

在这里插入图片描述

思路:

这道题还是可以运用模版,很容易就能想到,只要在原数组后再补一段同样数组就行,也就是数组长度翻倍

代码:
/**
 * @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)

写在最后:
栈 可以啊

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值