每日温度---力扣
Posted 穿迷彩服的鲨鱼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日温度---力扣相关的知识,希望对你有一定的参考价值。
前言
请根据每日 气温 列表,重新生成一个列表。对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。
一、示例
例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。
提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。
二、代码解析
1.每日温度
代码如下(示例):
vector<int> dailyTemperatures(vector<int>& T)
{
#pragma region 超时
/*暴力解法一*/
int n = T.size();
int index = 0;
vector<int> newT(n);
for (int i = 0; i < n; ++i)
{
for (int j = i+1; j < n; j++)
{
if (T[j]>T[i])
{
newT[i] = j - i;
index = -1;
break;
}
}
if (index==0)
{
newT[i] = 0;
}
}
return newT;
#pragma endregion
#pragma region 不超时
/*暴力解法二
* 对于温度列表中的每个元素 T[i],需要找到最小的下标 j,使得 i < j 且 T[i] < T[j]。
* 由于温度范围在 [30, 100] 之内,因此可以维护一个数组 next 记录每个温度第一次出现的下标。
* 数组 next 中的元素初始化为无穷大,在遍历温度列表的过程中更新 next 的值。
* 反向遍历温度列表。对于每个元素 T[i],在数组 next 中找到从 T[i] + 1 到 100 中每个温度第一次出现的下标,
* 将其中的最小下标记为 warmerIndex,则 warmerIndex 为下一次温度比当天高的下标。
* 如果 warmerIndex 不为无穷大,则 warmerIndex - i 即为下一次温度比当天高的等待天数,最后令 next[T[i]] = i。
* 为什么上述做法可以保证正确呢?因为遍历温度列表的方向是反向,
* 当遍历到元素 T[i] 时,只有 T[i] 后面的元素被访问过,即对于任意 t,当 next[t] 不为无穷大时,一定存在 j 使得 T[j] == t 且 i < j。
* 又由于遍历到温度列表中的每个元素时都会更新数组 next 中的对应温度的元素值,因此对于任意 t,
* 当 next[t] 不为无穷大时,令 j = next[t],则 j 是满足 T[j] == t 且 i < j 的最小下标。
*/
int n = T.size();
vector<int> ans(n), next(101, INT_MAX);
for (int i = n - 1; i >= 0; --i)
{
int warmerIndex = INT_MAX;
for (int t = T[i] + 1; t <= 100; ++t)
{
warmerIndex = min(warmerIndex, next[t]);
}
if (warmerIndex != INT_MAX)
{
ans[i] = warmerIndex - i;
}
next[T[i]] = i;
}
return ans;
#pragma endregion
#pragma region 不超时
/*单调栈*/
int n = T.size();
vector<int> ans(n);
stack<int> s;
for (int i = 0; i < n; ++i)
{
while (!s.empty() && T[i] > T[s.top()])
{
int previousIndex = s.top();
ans[previousIndex] = i - previousIndex;
s.pop();
}
s.push(i);
}
return ans;
#pragma endregion
}
2.测试代码
代码如下(示例):
#include<vector>
#include <iostream>
#include <stack>
using namespace std;
vector<int> dailyTemperatures(vector<int>& T)
{
#pragma region 超时
/*暴力解法一*/
int n = T.size();
int index = 0;
vector<int> newT(n);
for (int i = 0; i < n; ++i)
{
for (int j = i+1; j < n; j++)
{
if (T[j]>T[i])
{
newT[i] = j - i;
index = -1;
break;
}
}
if (index==0)
{
newT[i] = 0;
}
}
return newT;
#pragma endregion
#pragma region 不超时
/*暴力解法二
* 对于温度列表中的每个元素 T[i],需要找到最小的下标 j,使得 i < j 且 T[i] < T[j]。
* 由于温度范围在 [30, 100] 之内,因此可以维护一个数组 next 记录每个温度第一次出现的下标。
* 数组 next 中的元素初始化为无穷大,在遍历温度列表的过程中更新 next 的值。
* 反向遍历温度列表。对于每个元素 T[i],在数组 next 中找到从 T[i] + 1 到 100 中每个温度第一次出现的下标,
* 将其中的最小下标记为 warmerIndex,则 warmerIndex 为下一次温度比当天高的下标。
* 如果 warmerIndex 不为无穷大,则 warmerIndex - i 即为下一次温度比当天高的等待天数,最后令 next[T[i]] = i。
* 为什么上述做法可以保证正确呢?因为遍历温度列表的方向是反向,
* 当遍历到元素 T[i] 时,只有 T[i] 后面的元素被访问过,即对于任意 t,当 next[t] 不为无穷大时,一定存在 j 使得 T[j] == t 且 i < j。
* 又由于遍历到温度列表中的每个元素时都会更新数组 next 中的对应温度的元素值,因此对于任意 t,
* 当 next[t] 不为无穷大时,令 j = next[t],则 j 是满足 T[j] == t 且 i < j 的最小下标。
*/
int n = T.size();
vector<int> ans(n), next(101, INT_MAX);
for (int i = n - 1; i >= 0; --i)
{
int warmerIndex = INT_MAX;
for (int t = T[i] + 1; t <= 100; ++t)
{
warmerIndex = min(warmerIndex, next[t]);
}
if (warmerIndex != INT_MAX)
{
ans[i] = warmerIndex - i;
}
next[T[i]] = i;
}
return ans;
#pragma endregion
#pragma region 不超时2
/*单调栈三*/
int n = T.size();
vector<int> ans(n);
stack<int> s;
for (int i = 0; i < n; ++i)
{
while (!s.empty() && T[i] > T[s.top()])
{
int previousIndex = s.top();
ans[previousIndex] = i - previousIndex;
s.pop();
}
s.push(i);
}
return ans;
#pragma endregion
}
int main()
{
vector<int> nums = { 73, 74, 75, 71, 69, 72, 76, 73 };
vector<int> n = dailyTemperatures(nums);
for (int i = 0; i < n.size(); i++)
{
cout << n[i] << " ";
}
return 0;
}
3.结果
三、C++ stack 用法
C++ Stack(堆栈) 是一个容器类的改编,为程序员提供了堆栈的全部功能,——也就是说实现了一个先进后出(FILO)的数据结构。
c++ stl栈stack的头文件为: #include <stack>
1.成员函数
empty() 堆栈为空则返回真
pop() 移除栈顶元素
push() 在栈顶增加元素
size() 返回栈中元素数目
top() 返回栈顶元素
总结
以上是关于每日温度---力扣的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 739. 每日温度 Daily Temperatures (Medium)