一、介绍
1.题目描述
题目链接:https://leetcode-cn.com/problems/daily-temperatures/
请根据每日 气温 列表 temperatures ,请计算在每一天需要等几天才会有更高的温度。如果气温在这之后都不会升高,请在该位置用 0 来代替。
2.测试样例
[73,74,75,71,69,72,76,73]
# [1,1,4,2,1,1,0,0]
[30,40,50,60]
# [1,1,1,0]
[73,69,72,74]
# [3,1,1,0]
二、题解
1、暴力
(1)普通暴力🟢(超时)
最容易想到的一个解法就是直接暴力,对每个数字,向后查找最近的大于它的数字,但是这种做法的复杂度将达到n²,超过时限
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temp) {
int n=temp.size();
vector<int> ans;
int i,j;
// 遍历每个数
for(i=0;i<n-1;i++){
for(j=i+1;j<n;j++){
// 后面的数大于时,加入到答案
if(temp[j]>temp[i]){
ans.push_back(j-i);
break;
}
}
// 若没有更大的数,加入答案0
if(j==n)ans.push_back(0);
}
// 最后一个答案必为0
ans.push_back(0);
return ans;
}
};
(2)改进暴力🔴
由于我们要在一个数的后面找到更大的数,可以考虑从后向前遍历。边遍历边记录【离前面最近的】【各个更大的数】。
实现思路:
- a数组为传入的温度数据,next数组记录每个温度第一次出现的下标【即更近的下标】【由于温度<=100,数组长度101,初始全为INT_MAX】,t用于在遍历中标更新最小下标。
- 当前温度a[i],看next中是否记录了[a[i]+1,100]的温度下标,找到最小的下标更新t
- 若t=INT_MAX,说明未找到。反之,则当前下标对应的答案为t-i;
- 更新next[a[i]]=i,即a[i]温度对应的更近下标是i。
- 重复234步骤
以[73,69,72,74]为例:
- 从74(下标3)开始遍历,next中无75-100对应的下标,对应ans=0,记录next[74]=3
- 遇到72(下标2),next中有73-100对应的下标,最近的是next[74]=3,对应ans=3-2=1,记录next[72]=2
- 遇到69(下标1),next中有70-100对应的下标,最近的是next[72]=2,对应ans=2-1=1,记录next[69]=1
- 遇到73(下标0),next中有74-100对应的下标,最近的是next[74]=3,对应ans=3-0=3,记录next[73]=0
- 结束,得到答案[3,1,1,0]
参考链接:https://leetcode-cn.com/problems/daily-temperatures/solution/mei-ri-wen-du-by-leetcode-solution/
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& a) {
int n=a.size();
// ans记录答案,next记录该温度的最小下标
vector<int> ans(n),next(101,INT_MAX);
// 从后向前遍历
for(int i=n-1;i>=0;i--){
// 当前温度为a[i],找到a[i]+1至100的最近下标
int t=INT_MAX;
for(int temp=a[i]+1;temp<=100;temp++){
// 若存在a[i]+1至100的温度,更新最近下标
t=min(t,next[temp]);
}
// 下标存在,记录答案
if(t!=INT_MAX) ans[i]=t-i;
// 当前温度的下标为新的最近下标
next[a[i]]=i;
}
return ans;
}
};

2、栈🟢
另一种想法就是利用栈,推入小的数,遇到大的数时弹出,计算数字下标距离。
这里要注意的是,我们推入栈的应该是下标而不是数字,因为若推入数字,弹出后无法再获得该数字对应的结果。
【错误做法】若推入的是数字,以[73,69,72,74]为例
-
推入73,69
-
遇到72后弹出69,记录69对应的结果是1。弹出69,推入72
-
遇到74,弹出72,对应结果为1。再弹出73,会误以为对应结果是2。
【正确做法】因此我们要采用推入下标的方式。
-
推入0,1
-
遇到72后,72>69【即栈顶指向的值】,弹出下标1,记录69对应的结果是下标相减2-1=1。推入下标2
-
遇到74,74>72,弹出栈顶下标2,记录72对应的结果是下标相减3-2=1。
- 继续 74>73,弹出栈顶下标0,记录73对应的结果是下标相减3-0=3。
-
对于栈中剩余元素,全部弹出并设置对应结果为0
-
得到结果[3,1,1,0]
注意事项:
- 栈中储存下标而不是数字
- 原地修改。由于弹出数字的同时就会得到答案,数字不会再被二次使用,因此可以在原vector上更新数值为最终的天数答案
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temp) {
int n=temp.size();
stack<int> stk;
// 推入第一个数的下标
stk.push(0);
int t=0;
for(int i=1;i<n;i++){
t=stk.top();
// 当遇到更大的
while((!stk.empty())&&temp[i]>temp[t]){
// 弹出,坐标相减=答案,原地更新答案
temp[t]=i-t;
stk.pop();
// 更新t
if(!stk.empty()) t=stk.top();
}
stk.push(i);
}
// 栈中剩余元素对应的答案均为0
while(!stk.empty()){
temp[stk.top()]=0;
stk.pop();
}
return temp;
}
};

本文解析LeetCode上的每日温度问题,提供两种解决方案:一种是通过改进暴力法降低时间复杂度,另一种是利用栈实现高效求解。文章详细介绍了每种方法的实现思路及代码示例。
2267

被折叠的 条评论
为什么被折叠?



