一、题目:
根据每日气温列表,请重新生成一个列表,对应位置的输出是需要再等待多久温度才会升高超过该日的天数。如果之后都不会升高,请在该位置用 0 来代替。
例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。
提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。
二、自己动手做
class Solution:
def dailyTemperatures(self, T: List[int]) -> List[int]:
length = len(T)
for i in range(length):
if i == length-1:
break
for j in range(length-i):
if j+i == length-1:
T[i] = 0
break
if T[i] < T[j+i+1]:
T[i] = j+1
break
else:
continue
T[length-1] = 0
return T
总结:用自己的逻辑做的,我想有这样一个板块,这个板块能够看到我的进步,不过现在真的还是挺差的,实现了几个少量的每日温度,对于温度数太多的官方要求耗时太长,就相当于官方告诉我:小伙子,你现在的水平还是很基础的,仍要努力哦!好吧,那让我们看看官方的做法。
三、边看边学
1.栈:栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。栈某种意义上讲,它像是一个开口的盒子,先放进去的东西总是会被后放进去的东西压在下面,那么如果想拿出被压住的东西,必须要先取出顶部的东西,也就是后放进去的东西。
2.单调栈:
单调递增栈:栈中数据出栈的序列为单调递增序列
单调递减栈:栈中数据出栈的序列为单调递减序列
3.C++中的<>:,<>括号中的参数叫模板形参,模板形参和函数形参很相像,模板形参不能为空。一但声明了模板函数就可以用模板函数的形参名声明类中的成员变量和成员函数,即可以在该函数中使用内置类型的地方都可以使用模板形参名。有<>就是再定义模板了。
4.C++中的vector:详情见https://blog.csdn.net/weixin_41743247/article/details/90635931,另一个博主的文章,十分清楚。vector的优势我查了下,动态数组,美数组效率高,但是比数组好用,主要的好处是可以动态的增长长度,定义一个vector类型的变量时,并不需要指定它的容量是多少,如果有需要,只管往里面push数据。
本文用到语法的我复制过来了:
//定义具有10个整型元素的向量,且给出的每个元素初值为1
vectora(10,1);
5.C++的for循环思路:
for循环的执行顺序如下:
for(a;b;c)
{
d;
}
进入循环执行a;//只是进入的时候执行
执行b; //条件为真才执行d,不然跳出for了
执行d;
执行c;
再回到第2步开始执行,因此在循环体中,i++和++i的作用是一样的,但是++i的耗时要短。
6.while用于循环语句,而if用于判断和分支语句。
for循环里配while循环:只需要一个i作为控制循环,第二个循环判定条件复杂。(本文)
for循环里for循环:需要i,j两个来控制循环,循环判定条件简单。
7.发现循环中的变量类型很多人用auto,自动判定,因为变量生存环境比较小,所以无所谓想那么多。。。(现在我是这么认为的,以后发现不对再改。读者慎重判定,如果有想法请私信或者评论。)
8.Python里面的用list作为动态数组,(现在我是这么认为的,以后发现不对再改。读者慎重判定,如果有想法请私信或者评论。)
ans = [0] * len(T)=》创建一个全是0,长度跟T数组一样的数组
9.Python创建堆栈:stack = []
while:while stack and T[stack[-1]] < T[i](其中的&&直接用了 and,就很舒服。)
将i添加到栈顶:stack.append(i)
四、题解
方法一:C++利用动态数组vector,单调栈。
建议别看官方的,有点太官方,不适合小白,多看看点赞多的大佬,讲的通俗易懂。。。自己写的时候有一点没搞清楚,就是堆栈里面的原来是动态数组的下标值,标在程序里面了。
这是我模仿着写的:
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& T) {
int n = T.size();
vector<int>last(n,0);
stack<int>md;
for(int i=0;i<n;++i){
while(!md.empty()&&T[i]>T[md.top()]){ # md.top栈顶放的是下标,所以需要T[]指针调用
last[md.top()] = i - md.top();
md.pop();
}
md.push(i);
}
return last;
}
};
这个是人家用时最短的写的同款:
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& T) {
stack<int> stk;
vector<int> res(T.size(), 0);
for(int i = 0; i < T.size(); i++){
while(!stk.empty() && T[stk.top()] < T[i]){
res[stk.top()] = i - stk.top();
stk.pop();
}
stk.push(i);
}
return res;
}
};
方法二:Python版本单调栈,直接粘贴过来的别人的,思路懂了编程语言还是很容易看懂的。
class Solution:
def dailyTemperatures(self, T: List[int]) -> List[int]:
# 可以维护一个存储下标的单调栈,从栈底到栈顶的下标对应的温度列表中的温度依次递减。
# 如果一个下标在单调栈里,则表示尚未找到下一次温度更高的下标。
ans = [0] * len(T)
stack = []
for i in range(len(T)):
while stack and T[stack[-1]] < T[i]: # 栈不为空 && 栈顶温度小于当前温度
ans[stack[-1]] = i - stack[-1]
stack.pop()
stack.append(i)
return ans
五、我的感受
用上现有的一些武器,思路就复杂了,程序就简单了,效率就高了。
不用武器,思路简单了,程序就复杂了,效率就低了。(例如:栈)