当前位置: 首页 > news >正文

LeetCode刷题记录----739.每日温度(Medium)

2025/9/11

题目(Medium):


我的思路:

暴力遍历比大小:

最简单直观的算法,直接从当前位置往后遍历,找到第一个比当前温度高的温度所在的位置。然后用它的位置减去当前元素所在位置即可

具体代码如下:

class Solution {
public:vector<int> dailyTemperatures(vector<int>& temperatures) {int curIndex = 0;int n = temperatures.size();vector<int> res(n, 0);for(int i = 0; i < n; i++){for(int j = i+1; j < n; j ++){if(temperatures[j] > temperatures[i]){res[i] = j - i;break;}}}return res;}
};

时间复杂度:O(N^2)【最糟糕的情况是每个位置都需要遍历到数组末尾才能查找到】

空间复杂度:O(1)

虽然可以,但是会超时。


优化思路:

1.优化的暴力解法

我们可以观察到,温度的范围值是[30,100]这个固定的区间内。因此我们可以直到对于每个温度t,可以比它高的温度范围是[t+1, 100](100度的话肯定不存在比它更高的温度了)。

因此我们可以用一个数组next来记录[30,100]这个区间里的温度第一次出现的位置。从而当我们需要得到当前温度t的下一个更高温的索引的时候,去next中检索到最小的索引值即可。

但是我们要怎么保证我们在温度t位置的时候,next数组中记录的索引值就是对于t之后的更高温度的最小索引位置呢?我们可以通过倒着遍历温度数组的时候更新next数组的方式。这样就可以保证里面的最小索引值只是对当前的温度而言的。

具体代码如下:

class Solution {
public:vector<int> dailyTemperatures(vector<int>& temperatures) {//1.next数组标记每个温度值第一次出现的位置int n = temperatures.size();vector<int> res(n), next(101, INT_MAX);//倒着遍历for(int i = n-1; i >=0; i--){int warmIndex = INT_MAX;  //比当前位置更温暖的下标//先去里面查找最小的下标值for(int j = temperatures[i] + 1; j <= 100; j++){warmIndex = min(warmIndex, next[j]);    //找到[t+1, 100]这个范围中最小的下标值}if(warmIndex != INT_MAX){//说明找到了res[i] = warmIndex - i;}//更新当前的next数组next[temperatures[i]] = i;}return res;}
};

时间复杂度:O(MN)【M是每次遍历[t+1,100]范围的next数组的时候的开销,N是便遍历完整个温度数组的开销】

空间复杂度:O(M)【next数组的开销】

再怎么样M的长度是固定的,不会因为N越来越大而导致时间复杂度指数级增长,因此比我的那个在N大的情况下更好的

2.单调栈

因为我们知道,当前位置的更高温度的答案值是由【比当前温度更高的后面某天的索引值-当前天索引值】得到的,因此我们解题的关键在于由后面得到索引值两个词中。

由后面得到暗示我们温度的比较有一种后进先出进行比较的特性,因此符合栈的操作规律。而比较完之后如何得出天数值就需要索引值进行相减,因此我们可以知道往栈中压入索引值可以是我们需要的信息。

那接下来我们就需要定义一下入栈和出栈的规矩,遍历温度数组并进行以下操作:

①当栈为空的时候,把当前位置索引值入栈

②当栈不为空的时候,把当前位置温度和栈顶元素比较,如果比栈顶元素小,就也把索引值i入栈;如果比栈顶元素大,那就让栈顶元素preIndex弹出来,并更新栈顶元素对应的答案值 = i - preIndex,一直重复直到栈顶元素大于 等于 当前元素了 或者 栈为空了为止

class Solution {
public:vector<int> dailyTemperatures(vector<int>& temperatures) {//利用单调栈int n = temperatures.size();vector<int> res(n);stack<int> stk;     //单调栈,保证内部从底到顶是单调递减的,遇到破坏递减的数要加入的时候弹出直到重新递减了为止for(int i = 0; i < n; i++){if(stk.empty()){//栈为空,直接压入索引值(不必压入数值,因为可以根据索引值从数组中获取,同时又保留位置信息stk.push(i);}else{//栈不为空,要判断是否破坏了当前栈的单调性while(!stk.empty() && temperatures[i] > temperatures[stk.top()]){//破坏了,把所有比当前温度更低的索引值弹出来int preIndex = stk.top();stk.pop();res[preIndex] = i - preIndex;}stk.push(i);}}return res;}
};

时间复杂度:O(N)【一次遍历就可以解决】

空间复杂度:O(N)【最坏需要N长度的空间来存储】

下面还有个进一步精简的版本,逻辑完全一样的也,只是合并了一些分支:

class Solution {
public:vector<int> dailyTemperatures(vector<int>& temperatures) {//利用单调栈int n = temperatures.size();vector<int> res(n);stack<int> stk;     //单调栈,保证内部从底到顶是单调递减的,遇到破坏递减的数要加入的时候弹出直到重新递减了为止for(int i = 0; i < n; i++){//确保当前栈是单调递减的while(!stk.empty() && temperatures[i] > temperatures[stk.top()]){//破坏了,把所有比当前温度更低的索引值弹出来int preIndex = stk.top();stk.pop();res[preIndex] = i - preIndex;}//压入栈stk.push(i);}return res;}
};

总结:

①对于一些题目,即使用暴力解法,也要注意一下题目给出的一些限制条件。通过利用它们能够让我们的暴力解法稍微得到一点点优化

②对于要比较后面的值和当前值的大小,并关联到索引值的时候,可以通过最小栈来解决。并在栈中压入最需要的索引值作为记录。因为我们可以轻易由索引值得到温度值,但是没办法很快用温度值得到索引值。


文章转载自:

http://oZkowHTo.hnmbq.cn
http://pGO5Mcur.hnmbq.cn
http://JnpB6tNa.hnmbq.cn
http://3u0TQv8B.hnmbq.cn
http://K5jsviXW.hnmbq.cn
http://LOIVLQQk.hnmbq.cn
http://VEBnvz6F.hnmbq.cn
http://vEhKO02G.hnmbq.cn
http://isqhUnEg.hnmbq.cn
http://xCU6qn8H.hnmbq.cn
http://idYHRJWh.hnmbq.cn
http://GXrBGoo9.hnmbq.cn
http://ovuPzpuK.hnmbq.cn
http://lSAfxkjH.hnmbq.cn
http://7A5YfRUa.hnmbq.cn
http://tmdwb1QQ.hnmbq.cn
http://F33tfErn.hnmbq.cn
http://X3bju11K.hnmbq.cn
http://KB7UIWo6.hnmbq.cn
http://Ks7b0xPB.hnmbq.cn
http://4acums9A.hnmbq.cn
http://htNBd1yX.hnmbq.cn
http://sx8oN7Fe.hnmbq.cn
http://cCi2f8if.hnmbq.cn
http://siU20egW.hnmbq.cn
http://IYr1w1CS.hnmbq.cn
http://KFyaOCUS.hnmbq.cn
http://U2cFGyGF.hnmbq.cn
http://Lva1aHRD.hnmbq.cn
http://uE530r3I.hnmbq.cn
http://www.dtcms.com/a/378999.html

相关文章:

  • eNSP华为无线网测试卷:AC+AP,旁挂+直连
  • 开源多模态OpenFlamingo横空出世,基于Flamingo架构实现图像文本自由对话,重塑人机交互未来
  • 光路科技将携工控四大产品亮相工博会,展示工业自动化新成果
  • matlab实现相控超声波成像仿真
  • 【C】Linux 内核“第一宏”:container_of
  • Dinky 是一个开箱即用的一站式实时计算平台
  • Vue3内置组件Teleport/Suspense
  • Python打印格式化完全指南:掌握分隔符与行结尾符的高级应用
  • 实体不相互完全裁剪,请检查您的输入
  • 分数阶傅里叶变换(FRFT)的MATLAB实现
  • ARM (6) - I.MX6ULL 汇编点灯迁移至 C 语言 + SDK 移植与 BSP 工程搭建
  • unsloth微调gemma3图文代码简析
  • 【ECharts ✨】ECharts 自适应图表布局:适配不同屏幕尺寸,提升用户体验!
  • wpf依赖注入驱动的 MVVM实现(含免费源代码demo)
  • Python的f格式
  • 技术视界 | 末端执行器:机器人的“手”,如何赋予机器以生命?
  • 从零开始使用 axum-server 构建 HTTP/HTTPS 服务
  • 简直有毒!索伯ACL撕裂,雷霆四年报销三个新秀!
  • 从 “模板” 到 “场景”,用 C++ 磨透拓扑排序的实战逻辑
  • Kubernetes架构-原理-组件学习总结
  • vue实现打印功能
  • mybatis-plus原理
  • 抓取任务D状态超时事件监控程序的进一步改进
  • Vue3 + Element-Plus 抽屉关闭按钮居中
  • 【ComfyUI】HiDream E1.1 Image Edit带来更高精度的图像与文本编辑
  • MySQL 数据库_01
  • Redis 大 Key 与热 Key:生产环境的风险与解决方案
  • (k8s)Kubernetes 资源控制器关系图
  • 华为云/本地化部署K8S-查看容器日志
  • 探索大语言模型(LLM):Open-WebUI的安装