leetcode_739:每日温度

1. 暴力破解法

这个题目本身来说直接暴力根本不难,只是暴力的话时间复杂度相对较高。暴力也就是遍历每一个元素,然后从目标元素触发向后找,找到第一个比他大的数字位置,然后用此位置减去目标元素所在的位置就是两者的间隔。代码如下:

    public int[] dailyTemperatures(int[] T) {
        int[] result = new int[T.length];
        for (int i = 0; i < T.length; ++i) {
            int j = i+1;	//从它后一个元素出发,向后找
            for (; j < T.length && T[j] <= T[i]; ++j);
            if (j >= T.length)	//找到最后也没有,则为0
                result[i] = 0;
            else {
                result[i] = j-i;	//否则就是两个位置相减
            }
        }
        return result;
    }

2. 使用Next数组(其实就是result)

我其实是想到了从后往前遍历,但是只是想到了这个点,没有想到怎么做。思路是采用的pulsaryu的思路(原谅我看不懂官方解答的那一套)。

通过他的图,我们看一下这个例子。具体就是我们从后往前遍历,加入我们现在遇到了75。我们首先判断75后面相邻的元素是不是比它大,发现是71不如它大,那我们接下来怎么找呢。我们已经知道下一个比71大的是在71后面两个位置上的数,因为它的位置刚才我们求过了是2,所以我们直接跳到71后面的两个位置上,也就是72那儿,也就略过了69,因为通过这个2我们知道69肯定比71小。然后依次类推,72还是比75小,然后我们通过这个1知道比72大的第一个数就在它后面也就是76,于是我们又到了76,发现找到了,就可以通过下标相减得到这个距离。如果到最后都是没找到,那么这个位置就为0了。
在这里插入图片描述
代码如下:

    public int[] dailyTemperatures(int[] T) {
        int[] result = new int[T.length];
        result[T.length-1] = 0;		//最后一个肯定为0
        for (int i = T.length-2; i >= 0; --i) {		//从后向前遍历
            int j = i+1;	//从此元素出发向后找
            //找第一个大于它的值,要注意result[j]!=0保证后面还有比T[j]大的,
            //如果它为0,可能会死循环
            //所以这三个条件的先后顺序是不能改变的
            while (j < T.length && T[j] <= T[i] && result[j] != 0) {	
                j += result[j];
            }
            if (j < T.length && T[j] > T[i])	//确实有这样的值存在
                result[i] = j-i;
            else	//不存在设置为0
                result[i] = 0;
        }
        return result;
    }

不得不说这种解法是最快的。

3. 单调递减栈

这种解法就是从前向后遍历,保证栈内元素都是递减的,如果遇到一个元素比栈顶的大,则要把栈内比此元素小的所有值都弹出来,并且设置相应的结果。因此这里我用的栈是一个Pair<Integer,Integer>类型的,key是元素的值,value是元素的位置。这样在设置结果的时候直接可以用result[stack.peek().getValue()] = index - stack.peek().getValue(),其中index是当前元素的下标。代码如下:

    public int[] dailyTemperatures(int[] T) {
        int[] result = new int[T.length];
        //存放的是一个整数值和它的位置,是个单调递减栈
        Stack<Pair<Integer, Integer>> stack = new Stack<>();    
        stack.push(new Pair<>(T[0], 0));
        int index = 1;
        while (!stack.empty() && index < T.length) {
        	//新压进去的一定是变小的
            while (index < T.length && T[index] <= stack.peek().getKey()) {  
                stack.push(new Pair<>(T[index], index++));
            }
            if (index == T.length)
                break;
            //遇到递增的元素,把栈内比它小的都弹出来,并且设置相应的值
            while (!stack.empty() && T[index] > stack.peek().getKey()) {
                result[stack.peek().getValue()] = index - stack.pop().getValue();
            }
            //并把当前元素放进去
            stack.push(new Pair<>(T[index], index++));
        }
        //栈里剩余的都是比较大的,直接设置为0
        while (!stack.empty()) {
            result[stack.pop().getValue()] = 0;
        }
        return result;
    }
发布了96 篇原创文章 · 获赞 2 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/reachwang/article/details/103543842