系列文章目录
前言
每天进步一点点!!!
一、背景
来源:力扣
链接: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)
总结
多思考,正向不行,反向试试。存数值不行,试试存放下标。
总而言之,套路就那么几个,加加油,就能搞出来!!!
喜欢就点个赞叭!