14 力扣热题刷题记录之第739题每日温度

系列文章目录

力扣热题刷题记录

前言

每天进步一点点!!!

一、背景

在这里插入图片描述

来源:力扣
链接:https://leetcode-cn.com/problems/daily-temperatures/

二、我的思路

1.双循环暴力求解

本来是不想这样做的,但是真的想不到其它办法了,于是开始写代码,但是吧,超时,我能怎么办!!!

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
       vector<int> answer(temperatures.size(),0);
       for (int i=0;i<temperatures.size();i++)
       {
           for (int j=i+1;j<temperatures.size();j++)
           {
               if (temperatures[j]>temperatures[i])
               {
                   answer[i]=j-i;
                   break;
               }
           }
       } 
       return answer;
    }
};

2.用栈存放数组下标

超时怎么办,只能另外想办法了。

艾,我这个标签是栈,我咋用栈呢?把数值存放进去,没有找到比他大的就留在栈里面,但是当找到比他大的,我怎么知道中间隔了多少元素?

有了,用map!额,map好像不管用,记录栈顶元素的位置下标,好像可以,就是麻烦了点,还加大内存占用。等会,之前我做过题目不一定是存放数组值啊,也可以是存放下标,不如,试一试存放下标吧。

哈哈哈哈,果然,下标有用。当遇到大于栈内下标对应的数组元素的时候,让栈内的元素一直出栈,直到不符合条件。

什么时候不符合条件?

a、栈里没有元素了。
b、比较的不大于栈顶这个对应的数组值。

那么,最后栈内元素还有咋办?

说明没有比他们大的了呀,直接为0。嘿嘿,这个岂不是放在数组的初始化就可以,不用再来一个循环。

好啦,分析完毕,代码:

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
       vector<int> answer(temperatures.size(),0);//用于存储结果
       stack <int> my_stack;//用于存放下标

       //遍历数组
       for (int i=0;i<temperatures.size();i++)
       {  
           while (true)
           {
               //如果栈空,当前元素下标必须入栈
               if(my_stack.empty()) 
               {
                   my_stack.push(i);
                   break;
               }
               int u=my_stack.top();//取栈顶元素下标
               //如果大于栈顶对应的数组元素,开始计算值,并将那个下标出栈
               if (temperatures[i]>temperatures[u] )
               {
                    answer[u]=i-u;
                    my_stack.pop();
               }
               else
               {
                   my_stack.push(i);//如果不在大于栈顶元素,那么入栈当前下标
                   break;//并退出循环
               }   
           }  
       } 
       
       return answer;
    }
};

牛逼啊,过了,就是时间有一点点长。

稍等,看一眼官方思路。居然两个跟我一样,但是它的暴力怎么能过?算了,等会 再说,先看看它怎么写的,我去,这么简洁???

好吧,我也优化一下:

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
       vector<int> answer(temperatures.size(),0);//用于存储结果
       stack <int> my_stack;//用于存放下标

       //遍历数组
       for (int i=0;i<temperatures.size();i++)
       {  
           //栈不空时,且大于栈顶对应的数组元素,那么求值
           while (!my_stack.empty()&&temperatures[i]>temperatures[my_stack.top()])
            {             
                answer[my_stack.top()]=i-my_stack.top();
                my_stack.pop();
            }             
            my_stack.push(i);//如果不大于栈顶元素或者为空,那么入栈当前下标   
       } 
       return answer;
    }
};

三、官方的思路

啊哈,官方的思路和我一样,耶耶耶耶!!

等下,它的暴力解法怎么操作的?为啥不超时?我瞅瞅!

它的暴力是通过一个next数组优化过的,我的第二个循环是随着n变化的,它的第二个循环是固定70次,因为它按温度遍历,只有温度比当前高,且第一次出现,那么就认为可以求解了。实在是妙啊!!

1、反向遍历。不是正向的原因是因为要求得是后面哪个元素比当前的大,这就不利于记忆了呀。后面从前走,走过来哪个比当前大肯定是有记忆的。

2、next数组存放温度(30-100度)。而上述说的记忆就放在next数组里面。这个记忆对于相同的温度只记录下标最小的那个,即表示最新的值。就恰到好处的可以计算最后的结果了。

上代码:

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        int n = temperatures.size();
        vector<int> ans(n), next(101, INT_MAX);
        for (int i = n - 1; i >= 0; --i) {
            int warmerIndex = INT_MAX;
            for (int t = temperatures[i] + 1; t <= 100; ++t) {
                warmerIndex = min(warmerIndex, next[t]);
            }
            if (warmerIndex != INT_MAX) {
                ans[i] = warmerIndex - i;
            }
            next[temperatures[i]] = i;
        }
        return ans;
    }
};

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/daily-temperatures/solution/mei-ri-wen-du-by-leetcode-solution/
来源:力扣(LeetCode)

总结

多思考,正向不行,反向试试。存数值不行,试试存放下标。

总而言之,套路就那么几个,加加油,就能搞出来!!!

喜欢就点个赞叭!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值