给定一个整数数组 temperatures
,表示每天的温度,返回一个数组 answer
,其中 answer[i]
是指对于第 i
天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0
来代替。
写在之前---写的暴力枚举法,直接遍历每个数i,再遍历之后的数找到大于x的数j计算两者的距离,以的时间复杂度解决超时了----故记录新的解法
解决每日温度问题的两种解法
在这篇博客中,我们将讨论一种经典的算法题——“每日温度”,并展示两种不同的解法。这道题目要求你为每一天的温度找到下一次温度高于当前温度的天数,如果没有更高的温度,则返回 0。
题目描述: 给定一个由整数表示的温度列表,每个整数代表一天的温度。你需要返回一个列表,表示每一天距离下一个温度更高的天数。
暴力解法:双重循环
第一个解法是比较直观的暴力解法,采用了双重循环的方式。通过两层循环,外层循环逐日遍历每一天的温度,内层循环寻找下一个温度更高的日子。
代码实现:
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
for(int i=0;i<temperatures.size();i++){
int j=i;
while(j<temperatures.size()){
if(temperatures[j]>temperatures[i]){
temperatures[i]=j-i;
break;
}
j++;
}
if(j==temperatures.size()) temperatures[i]=0;
}
return temperatures;
}
};
分析
- 时间复杂度:O(n²),其中n是温度列表的长度。每一对温度之间都进行比较,最坏情况下会遍历每个元素两次。
- 空间复杂度:O(1),只使用了常数级的空间。
这种解法在实现上简单直观,但性能较差,特别是在处理大量数据时,会变得不够高效。
优化解法:使用栈
第二种解法使用了栈来优化算法的时间复杂度。我们利用栈来存储温度的索引,只有当遇到比栈顶元素温度更高的温度时,我们才能够更新结果并弹出栈顶元素。通过这种方式,避免了每次都要进行内层循环的重复计算。
代码实现:
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
int n = temperatures.size();
vector<int> ret(n, 0); // 结果数组,初始化为0
stack<int> st; // 栈,存储温度的索引
for(int i = 0; i < n; i++) {
// 如果当前温度比栈顶温度大,说明我们找到了一个答案
while(!st.empty() && temperatures[i] > temperatures[st.top()]) {
ret[st.top()] = i - st.top(); // 计算天数差
st.pop(); // 弹出栈顶
}
st.push(i); // 当前索引入栈
}
return ret;
}
};
分析
- 时间复杂度:O(n),其中n是温度列表的长度。每个元素最多入栈和出栈一次,因此每个元素的操作都被限制在O(1)。
- 空间复杂度:O(n),栈中最多会存储n个元素。
通过使用栈的方式,我们大大提高了算法的效率,避免了重复的内层循环,提升了计算速度。
总结对比
解法 | 时间复杂度 | 空间复杂度 | 描述 |
---|---|---|---|
暴力解法 | O(n²) | O(1) | 简单直观,但在数据量大时性能较差。 |
栈解法 | O(n) | O(n) | 更高效,适合处理大规模数据。 |
在实际应用中,栈解法无疑是更加高效的选择,特别是在数据量较大的时候,暴力解法可能会导致严重的性能瓶颈。
希望这篇博客能够帮助你更好地理解并比较这两种解法!如果你有其他问题,欢迎留言讨论。