LeetBook作业: 每日温度


题目地址

https://leetcode-cn.com/leetbook/read/queue-stack/genw3/


一、解题思路

朴素思维: 双层循环,利用两个指针寻找每一天温度之后的较高温度,返回两个指针的下标的差为answer[i]的值。示例中的测试用例是可以的,但是提交以后运行超时了。毕竟temperatures的最大长度是10^5。超时的测试用例是只有两个温度不停摆动的温度序列,这个点我一开始也没有考虑到。

转换思路:既然是栈的练习题,还是要充分利用栈的特性。而且最多就只能循环一次。我想到了链表的双指针。

二、作业记录

1.暴力代码

代码如下:

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {

        int n = temperatures.length;
        int[] answer = new int[ n ];
        int count = 0, i,j;

        Stack<Integer> warmer = new Stack();

        for(i = 0; i < n; i ++){
            count = 0;
            warmer.push(temperatures[i]);

            for(j = i+1; j < n; j++){

                if( temperatures[j] > warmer.peek()){
                    count = j-i;
                    warmer.pop();
                    break;
                }else {
                    continue;
                }
            }
            answer[i] = count;
            }          
        return answer;

    }
}

1.1 作业表现

表现如下:

在这里插入图片描述

这个测试用例足足刷了好几屏…可见暴力是不行的,只能靠智取。我的栈好像没有发挥正确的作用。改进,我相信不适用嵌套循环,变成两个循环。

2. 优化代码

测试用例:
[73,74,73,74,73,74,74,73]

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {

        int n = temperatures.length;
        int[] answer = new int[ n ];
        int  i,j;

        Stack<Integer> warmer = new Stack();

        i = 0;
        j = 1;     
        while (i < n && j < n){

            if(temperatures[i] < temperatures[j]){
                warmer.push(j);
                answer[i] = warmer.peek() - i;
                i++;
                j = i + 1;
            }else if(temperatures[i] == temperatures[j] && i != j) {

                i++;

            }else{
                j++;
            }
        }
               
        return answer;

    }
}

通过了上面的测试用例,但是还是出错了。

2.1 优化后提交结果

在这里插入图片描述
又尝试了一段时间后看了官方题解,我发现我的问题还是因为我僵在了要顺序给answer赋值这个坑里。
官方题解用单调栈,可以跳着给数组赋值。按照官方思路重新做一遍!

3. 官方思路优化的代码

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {

        Stack<Integer> warmer = new Stack();

        int n = temperatures.length;

        int[] answer = new int[n];

        int i = 0 ,preIndex;     

        for( i = 0; i < n; i++){

            int temperature = temperatures[i];
            
            while( !warmer.empty() && temperature > temperatures[ warmer.peek()]){
                preIndex = warmer.pop();
                answer[preIndex] = i - preIndex;   
            }
            warmer.push(i);
        }

        return answer;

    }
}

3.1 官方思路优化代码的表现

在这里插入图片描述
在这里插入图片描述
我很惊讶的就是用时表现很差, 仔细看起来,就是stack的实现上和官方有区别。于是,我使用了官方的栈的实现方式。

4. 用Deque实现栈后的代码

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {

        Deque<Integer> warmer = new LinkedList<Integer>();

        int n = temperatures.length;

        int[] answer = new int[n];

        int i = 0 ,preIndex;     

        for( i = 0; i < n; i++){

            int temperature = temperatures[i];
            
            while( !warmer.isEmpty() && temperature > temperatures[ warmer.peek()]){
                preIndex = warmer.pop();
                answer[preIndex] = i - preIndex;   
            }
            warmer.push(i);

        }

        return answer;

    }
}

4.1 执行表现

在这里插入图片描述
就是变化了一下数据的实现方式,执行用时就差了13s, 终于明白了为什么大佬们的代码中stack都是用Deque来实现的啦。


复杂度分析

时间复杂度: 暴力解法不用说就是O(n^2), 用了官方的思路单调栈的解法,复杂度就是O(n) 空间复杂度:两种解法的空间复杂度都是O(n),因为实际上都只是用栈来存储了温度的数组。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不争之德

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值