剑指 Offer II 038. 每日温度

剑指 Offer II 038. 每日温度

刷题第 12 天。GO!GO!GO!

原题

剑指 Offer II 038. 每日温度

请根据每日 气温 列表 temperatures ,重新生成一个列表,要求其对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。

示例 1:

输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]

示例 2:

输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]

示例 3:

输入: temperatures = [30,60,90]
输出: [1,1,0]

提示:

  • 1 <= temperatures.length <= 10^5
  • 30 <= temperatures[i] <= 100

解题思路

解决这道题目最直观的思路就是:将当天的温度与过去的温度进行比较,求出至少需要等待的天数。

所以,我们可以遍历每天的温度,将其与前面日子的温度进行比较,然后得到答案。

还需要弄明白以下几点:

  • 题目要求的是至少等待天数, 一个日子等待天数已经求出后,在后续日子的遍历中, 不需要再考虑它了
  • 当天的答案必须要留到后续循环中才能算出, 所以需要保存当天的数据留给后续处理
  • 最后一天的等待天数必定是 0

下面我们设当天温度为 curTemperture, 答案用数组 res 表示,preTemperture 表示前面某天的温度。

    int len = temperatures.length;
    ...
    for (int i = ..; i < len; ++i) {
        if (curTemperture > preTemperture) {
        // 为了确定答案, 所以我们还需要记录 preTemperture 是第几天的数据
        res[?] = i - ?
        ...
        ...
   		 }
	}

根据上面的描述, 我们很自然的想到用栈来处理(栈顶的数据正是最近的数据),由于栈只能保存一个对象,但是我们必须保存以下数据:

  • 温度多少?
  • 第几天的数据?
class Temperture{
    // 第几天的数据
    int day;
    // 当天的温度
    int val;
}
...
    
// Java 里的 Stack 是线程同步的, 考虑到性能, 所以这里用 Deque
Deque<Temperature> stack = new ArrayDeque<>();

有了以上的铺垫,我们就有思路了。

用栈存储过去的温度数据,并将当天的温度与栈中保存的温度进行比较,如果当天温度高,则弹出过去的数据,如此循环;结束当天的遍历时,要将当天的数据保存在栈中,以备后续使用。

完整代码

	class Solution {

		class Temperature {
			int day;
			int val;

			public Temperature(int day, int val) {
				this.day = day;
				this.val = val;
			}
		}
        
		public int[] dailyTemperatures(int[] temperatures) {
			Deque<Temperature> stack = new ArrayDeque<>();
			int len = temperatures.length;
			int[] result = new int[len];

			int preTemperature = temperatures[0];
			int startTime = 0;
			stack.push(new Temperature(startTime, preTemperature));
			int curTempreature;
			Temperature preTem;

			for (int i = 1; i < len; ++i) {
				curTempreature = temperatures[i];
				// 当前温度比前一天温度高时, 开始回推过去的温度
				while (curTempreature > preTemperature) {
					stack.pop();
					result[startTime] = i - startTime;
					if (stack.isEmpty()) {
						break;
					}
					preTem = stack.peek();
					startTime = preTem.day;
					preTemperature = preTem.val;
				}
				preTemperature = curTempreature;
				startTime = i;
				stack.push(new Temperature(i, curTempreature));
			}

			return result;
		}
	}

其他细节

计算机的寄存器个数是有限的, 像上面代码使用到的 stack 能保存的数据远远大于寄存器所能保存的数据;因此栈是在内存中的,而内存引用一般是性能的瓶颈,为了减少读写内存的次数;我们使用 preTemperaturestartTime 这样的本地变量 (一般存储在寄存器中) 来保存上一次读栈的数据。而不是将其直接与 stack.peek().valstack.peek().day 比较。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值