zoukankan      html  css  js  c++  java
  • 【LeetCode】739.每日温度(5种方法,详细图解)

    题目

    链接

    image-20200710223721212

    分析

    这道题目最 “难” 的一个点是题目的理解。

    给定列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],为啥输出就是 [1, 1, 4, 2, 1, 1, 0, 0]

    下面来一个个进行解释。

    对于输入 73,它需要 经过一天 才能等到温度的升高,也就是在第二天的时候,温度升高到 74 ,所以对应的结果是 1。

    对于输入 74,它需要 经过一天 才能等到温度的升高,也就是在第三天的时候,温度升高到 75 ,所以对应的结果是 1。

    对于输入 75,它经过 1 天后发现温度是 71,没有超过它,继续等,一直 等了四天,在第七天才等到温度的升高,温度升高到 76 ,所以对应的结果是 4 。

    对于输入 71,它经过 1 天后发现温度是 69,没有超过它,继续等,一直 等了两天,在第六天才等到温度的升高,温度升高到 72 ,所以对应的结果是 2 。

    对于输入 69,它 经过一天 后发现温度是 72,已经超过它,所以对应的结果是 1 。

    对于输入 72,它 经过一天 后发现温度是 76,已经超过它,所以对应的结果是 1 。

    对于输入 76,后续 没有温度 可以超过它,所以对应的结果是 0 。

    对于输入 73,后续 没有温度 可以超过它,所以对应的结果是 0 。

    好了,理解了题意我们来思考如何求解。

    1,最简单的方式是暴力求解,遍历每一个元素,然后再从当前元素往后找比它大的,找到之后记录下他俩位置的差值,然后停止内层循环,如果没找到默认为0。

    微信截图_20200611104024.png
    微信截图_20200611104034.png

        public int[] dailyTemperatures(int[] T) {
            int length = T.length;
            int[] res = new int[length];
            for (int i = 0; i < length; i++) {
                for (int j = i + 1; j < length; j++) {
                    if (T[j] > T[i]) {
                        res[i] = j - i;
                        break;
                    }
                }
            }
            return res;
        }
    

    2,暴力求解毕竟效率不高,我们还可以只用栈来解决,这个栈中存放的是数组元素的下标,我们画个图看下

    微信截图_20200611131851.png
    微信截图_20200611131905.png
    微信截图_20200611131914.png
    微信截图_20200611131924.png
    微信截图_20200611131933.png
    微信截图_20200611131941.png
    微信截图_20200611131949.png

    代码如下

        public int[] dailyTemperatures(int[] T) {
            Stack<Integer> stack = new Stack<>();
            int[] ret = new int[T.length];
            for (int i = 0; i < T.length; i++) {
                while (!stack.isEmpty() && T[i] > T[stack.peek()]) {
                    int idx = stack.pop();
                    ret[idx] = i - idx;
                }
                stack.push(i);
            }
            return ret;
        }
    

    3,我们还可以把栈改为数组的形式

        public int[] dailyTemperatures(int[] T) {
            int[] stack = new int[T.length];
            int top = -1;
            int[] res = new int[T.length];
            for (int i = 0; i < T.length; i++) {
                while (top >= 0 && T[i] > T[stack[top]]) {
                    int idx = stack[top--];
                    res[idx] = i - idx;
                }
                stack[++top] = i;
            }
            return res;
        }
    

    4,这题我们还可以参照第84. 柱状图中最大的矩形

    来看一下代码

        public int[] dailyTemperatures(int[] T) {
            int length = T.length;
            Stack<Integer> stack = new Stack<>();
            int[] res = new int[length];
            for (int i = 0; i < length; i++) {
                int h = T[i];
                if (stack.isEmpty() || h <= T[stack.peek()]) {
                    stack.push(i);
                } else {
                    int top = stack.pop();
                    res[top] = i - top;
                    i--;
                }
            }
            return res;
        }
    

    5,最后一种解法,这种更厉害,从后面开始查找,效率更高,击败了100%的用户,代码中有注释,大家自己看

    微信截图_20200611134941.png

        public int[] dailyTemperatures(int[] T) {
            int[] res = new int[T.length];
            //从后面开始查找
            for (int i = res.length - 1; i >= 0; i--) {
                int j = i + 1;
                while (j < res.length) {
                    if (T[j] > T[i]) {
                        //如果找到就停止while循环
                        res[i] = j - i;
                        break;
                    } else if (res[j] == 0) {
                        //如果没找到,并且res[j]==0。说明第j个元素后面没有
                        //比第j个元素大的值,因为这一步是第i个元素大于第j个元素的值,
                        //那么很明显这后面就更没有大于第i个元素的值。直接终止while循环。
                        break;
                    } else {
                        //如果没找到,并且res[j]!=0说明第j个元素后面有比第j个元素大的值,
                        //然后我们让j往后挪res[j]个单位,找到那个值,再和第i个元素比较
                        j += res[j];
                    }
                }
            }
            return res;
        }
              //然后我们让j往后挪res[j]个单位,找到那个值,再和第i个元素比较
                        j += res[j];
                    }
                }
            }
            return res;
        }
    
  • 相关阅读:
    怎样用Android Studio打多包名APK
    u-boot-2014.04移植FL2440(使用eclipse编辑uboot)
    power of two
    javascript的prototype经典使用场景
    git创建与管理远程分支【转】
    error:Flash Download failed-“Cortex-M3”,“Programming Algorithm”【转】
    内核签名【转】
    Android系统Recovery模式的工作原理【转】
    Android系统Recovery工作原理之使用update.zip升级过程分析(三)【转】
    Recovery模式【转】
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13307978.html
Copyright © 2011-2022 走看看