Java每日一题——>739. 每日温度(蛮力法,栈方法)

Posted stormzhuo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java每日一题——>739. 每日温度(蛮力法,栈方法)相关的知识,希望对你有一定的参考价值。

题目

这是LeetCode上的 [739,每日温度],难度为 [中等]

请根据每日 气温 列表 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 <= 105
  • 30 <= temperatures[i] <= 100

题解1(蛮力法)

我们可以在遍历每一天的温度时,让当前天的温度与当前天的温度后面的每一天的温度作比较,直到找到第一个最高温度的天数

代码实现

class Solution 
    public int[] dailyTemperatures(int[] temperatures) 
        // 创建一个数组,存放每一天需要等多少天才能有第一个最高温度
        int[] days = new int[temperatures.length];
        // 遍历每一天的温度,遍历过程中让当前天的温度与当前天的温度后面的每个天的温度作比较
        for (int i = 0; i < temperatures.length; i++) 
            for (int j = i + 1; j < temperatures.length; j++) 
                // 若当前天的温度小于当前天的温度后面的某一天的温度,则找到了当前天的温度第一个最高温度的天数
                if (temperatures[i] < temperatures[j]) 
                    // 第一个最高温度的天数减去当前天的温度的天数即为当前天需要等的天数
                    days[i] = j - i;
                    break;
                
            
        
        return days;
    

复杂度分析

假设输入的数组的长度为n

时间复杂度

在遍历每一天时,需要遍历当前天后面的每一天作比较,故时间复杂度为O(n2

空间复杂度

需要声明一个数组来记录每一天需要等多少天才有第一个最高温度,故空间复杂度为O(n)

题解2(栈方法)

蛮力法的缺点就是在遍历每一天温度时,需要把当前天的温度与当前天的温度后面的每个天的温度进行比较找出当前天第一个最高温度,即O(n2)

那么可不可以只比较两两相邻的天的温度找出当天的第一个最高的温度呢?如果可以那么时间复杂度就降到O(n)了

例如我们可以在遍历每一天的温度时借助一个辅助容器来比较两两相邻的天的温度

  1. 若当前天的温度没有前一天的温度,例如第一次循环时当前天的温度是第一天的温度,故没有前一天的温度,由于不知道后面还有没有比他更高的温度,则把当前天的温度的下标(当前遍历的下标)放进一个容器中

  2. 若当前天的温度有前一天的温度,则把当前天的温度和前一天的温度(也就是已经保存容器中的温度的 下标,通过下标就可以知道温度)进行比较

    • 若当前天的温度小于前一天的温度,则当前天的温度不是前一天的温度的第一个最高温度,因此可以把当前天的温度的下标放进一个容器中,因为不知道后面还有没有比他更高的温度
    • 若当前天的温度大于前一天的温度,则当前天的温度是前一天的第一个最高温度,因此就找到了前一天的第一个最高温度,把前一天的温度取出容器,即当前天的温度下标减去前一天温度下标就知道前一天需要等多少天才有第一个最高温度,之后让当前天重复最开始的1,2步

需要注意的是,前一天指的是相对的,即容器最后存放的天数为前一天,而不是实际的前一天

综上分析,此容器需要遵循先进后出的特点,因此可以使用栈来作为容器

代码实现

class Solution 
    public int[] dailyTemperatures(int[] temperatures) 
        // 创建一个栈,来存放遍历每一天的温度时当前天的前面每一天的天数
        Deque<Integer> stack = new LinkedList<>();
        // 创建一个数组,存放每一天需要等多少天才能有第一个最高温度
        int[] days = new int[temperatures.length];
        // 遍历每一天的温度
        for (int i = 0; i < temperatures.length; i++) 
            /* 当前天有前一天(即栈不为空),且当前天的温度大于前一天的温度,
               则说明找到前一天的第一个最高温度,前一天的温度出栈,值为前一天的天数
               当前天的天数(遍历过程的索引)减去前一天的天数,即可算出前一天需要等多少天才有第一个最高温度
               执行下一次迭代,判读是否满足循环条件*/
            while (!stack.isEmpty() && temperatures[stack.peek()] < temperatures[i]) 
                int pre = stack.pop();
                days[pre ] = i - pre ;
            
            /* 若当前天没有前一天*(栈为空)或当前天的温度小于前一天的的温度,都让当前天进栈
            * 因为不知道后面有没有比它更高的温度*/
            stack.push(i);
        
        return days;
    

复杂度分析

假设输入的数组的长度为n

时间复杂度

虽然上面代码使用了一个嵌套循环,当内层循环并不是每次都执行的,这是因为每一天的天数进栈,出栈各一次,即在遍历每一天时,每一天的天数最多有一次进栈和出栈操作。故内层循环的时间复杂度可以认为O(1),外层需要遍历每一天,故总的时间复杂度为O(n)

空间复杂度

需要声明一个数组来记录每一天需要等多少天才有第一个最高温度,空间复杂度为O(n,)需要一个栈来存放遍历过程中当前天前面的每一天的天数(下标),空间复杂度为O(n),故总的空间复杂度为2O(n) = O(n)

以上是关于Java每日一题——>739. 每日温度(蛮力法,栈方法)的主要内容,如果未能解决你的问题,请参考以下文章

Java每日一题——>739. 每日温度(蛮力法,栈方法)

Java每日一题——>剑指 Offer II 035. 最小时间差(三解,蛮力,排序,哈希)

Java每日一题——>剑指 Offer II 035. 最小时间差(三解,蛮力,排序,哈希)

Java每日一题——>剑指 Offer II 035. 最小时间差(三解,蛮力,排序,哈希)

Java每日一题——>剑指 Offer II 035. 最小时间差(三解,蛮力,排序,哈希)

739. 每日温度