每日温度---力扣

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() 返回栈顶元素

总结

在这里插入图片描述

以上是关于每日温度---力扣的主要内容,如果未能解决你的问题,请参考以下文章

算法系列——每日温度

算法系列——每日温度

栈 -- 739. 每日温度

LeetCode 739. 每日温度 Daily Temperatures (Medium)

LeetCode 739. 每日温度 Daily Temperatures (Medium)

Java每日一题——>739. 每日温度(蛮力法,栈方法)