代码随想录刷题Day58 | 739. 每日温度 | 496. 下一个更大元素 I

代码随想录刷题Day58 | 739. 每日温度 | 496. 下一个更大元素 I

739. 每日温度

题目:

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。

示例 1:

输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]

思路:

在使用单调栈的时候首先要明确如下几点:

  1. 单调栈里存放的元素是什么?

单调栈里只需要存放元素的下标i就可以了,如果需要使用对应的元素,直接T[i]就可以获取。

  1. 单调栈里元素是递增呢? 还是递减呢?

注意一下顺序为 从栈头到栈底的顺序,因为单纯的说从左到右或者从前到后,不说栈头朝哪个方向的话,大家一定会越看越懵。

这里我们要使用递增循序(再强调一下是指从栈头到栈底的顺序),因为只有递增的时候,加入一个元素i,才知道栈顶元素在数组中右面第一个比栈顶元素大的元素是i。

文字描述理解起来有点费劲,接下来我画了一系列的图,来讲解单调栈的工作过程。

使用单调栈主要有三个判断条件。

  • 当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况
  • 当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况
  • 当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况

把这三种情况分析清楚了,也就理解透彻了

接下来我们用temperatures = [73, 74, 75, 71, 71, 72, 76, 73]为例来逐步分析,输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。

首先先将第一个遍历元素加入单调栈 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7bxonroS-1670474740165)(https://dum1615.oss-cn-chengdu.aliyuncs.com/20210219124434172.jpg)]

加入T[1] = 74,因为T[1] > T[0](当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况),而我们要保持一个递增单调栈(从栈头到栈底),所以将T[0]弹出,T[1]加入,此时result数组可以记录了,result[0] = 1,即T[0]右面第一个比T[0]大的元素是T[1]。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4NyGXmrz-1670474740165)(https://dum1615.oss-cn-chengdu.aliyuncs.com/20210219124504299.jpg)]

加入T[2],同理,T[1]弹出

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qT5wL02Q-1670474740166)(https://dum1615.oss-cn-chengdu.aliyuncs.com/20210219124527361.jpg)]

加入T[3],T[3] < T[2] (当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况),加T[3]加入单调栈。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7VXV1UTn-1670474740166)(https://dum1615.oss-cn-chengdu.aliyuncs.com/20210219124610761.jpg)]

加入T[4],T[4] == T[3] (当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况),此时依然要加入栈,不用计算距离,因为我们要求的是右面第一个大于本元素的位置,而不是大于等于! [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PtLIszAP-1670474740166)(https://dum1615.oss-cn-chengdu.aliyuncs.com/20210219124633444.jpg)]

加入T[5],T[5] > T[4] (当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况),将T[4]弹出,同时计算距离,更新result 739.每日温度6

T[4]弹出之后, T[5] > T[3] (当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况),将T[3]继续弹出,同时计算距离,更新result 739.每日温度7

直到发现T[5]小于T[st.top()],终止弹出,将T[5]加入单调栈 739.每日温度8

加入T[6],同理,需要将栈里的T[5],T[2]弹出 739.每日温度9

同理,继续弹出 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c9INmTsG-1670474740168)(https://dum1615.oss-cn-chengdu.aliyuncs.com/2021021912490098.jpg)]

此时栈里只剩下了T[6]

739.每日温度11

加入T[7], T[7] < T[6] 直接入栈,这就是最后的情况,result数组也更新完了。 739.每日温度12

此时有同学可能就疑惑了,那result[6] , result[7]怎么没更新啊,元素也一直在栈里。

其实定义result数组的时候,就应该直接初始化为0,如果result没有更新,说明这个元素右面没有更大的了,也就是为0。

代码:

class Solution {
    public int[] dailyTemperatures(int[] tem) {
        //单调栈
        Stack<Integer> s = new Stack<>();
        int[] ans = new int[tem.length];
        for(int i = 0; i < tem.length; i++){
            if(s.empty() || tem[i] <= tem[s.peek()]){
                s.push(i);
                continue;
            }
            while(!s.empty() && tem[i] > tem[s.peek()]){
                int index = s.pop();
                ans[index] = i - index;
            }
            s.push(i);
        }
        return ans;
    }
}

496. 下一个更大元素 I

题目:

nums1 中数字 x下一个更大元素 是指 xnums2 中对应位置 右侧第一个x 大的元素。

给你两个 没有重复元素 的数组 nums1nums2 ,下标从 0 开始计数,其中nums1nums2 的子集。

对于每个 0 <= i < nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums2 确定 nums2[j]下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是 -1

返回一个长度为 nums1.length 的数组 ans 作为答案,满足 ans[i] 是如上所述的 下一个更大元素

示例 1:

输入:nums1 = [4,1,2], nums2 = [1,3,4,2].
输出:[-1,3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:
- 4 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。
- 1 ,用加粗斜体标识,nums2 = [1,3,4,2]。下一个更大元素是 3 。
- 2 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。

思路:

同上题每日温度

代码:

class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        Map<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < nums2.length; i++){
            map.put(nums2[i], -1);
        }
        Stack<Integer> s = new Stack<>();
        for(int i = 0; i < nums2.length; i++){
            if(s.empty() || nums2[i] <= nums2[s.peek()]){
                s.push(i);
                continue;
            }
            while(!s.empty() && nums2[i] > nums2[s.peek()]){
                int index = s.pop();
                map.put(nums2[index], nums2[i]);
            }
            s.push(i);
        }
        int[] ans = new int[nums1.length];
        for(int i = 0; i < nums1.length; i++){
            ans[i] = map.get(nums1[i]);
        }
        return ans;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值