代码随想录算法训练营第五十八天 | 739. 每日温度 496.下一个更大元素 I

739. 每日温度

给定一个整数数组 temperatures,表示每天的温度,返回一个数组 answer ,其中 answer[i]
 是指对于第 i天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位用 0来代替。

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

思路一:暴力破解

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int[] reslut=new int[temperatures.length];
        for(int i=0;i<temperatures.length;i++){
            for(int j=i+1;j<temperatures.length;j++){
                if(temperatures[j]>temperatures[i]){
                    int temp=j-i;
                    reslut[i]=temp;
                    break;
                }else{
                    reslut[i]=0;
                }
            }
        }
        return reslut;

    }
}

但是时间超出限制,所以这道题这个方法不可取

思路二:单调栈

通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了

本题单调栈中存储的是下标索引

使用单调栈主要有三个判断条件。

  • 当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况 存入栈中

  • 当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况 存入栈中

  • 当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况 弹出元素,并且记录结果

    reslut[stack.peek()]=i-stack.peek();

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int[] reslut=new int[temperatures.length];
        Deque<Integer> stack=new LinkedList<>();
        stack.push(0);
        for(int i=1;i<temperatures.length;i++){
            if(temperatures[i]<=temperatures[stack.peek()]){
                stack.push(i);
            }else{
                while(!stack.isEmpty()&&temperatures[i]>temperatures[stack.peek()]){
                    reslut[stack.peek()]=i-stack.peek();
                    stack.pop();
                }
                stack.push(i);
            }
        }
        return reslut;
    }
}

496. 下一个更大元素 I

nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x ****大的元素。

给你两个 没有重复元素 的数组 nums1 和 nums2 ,下标从 0 开始计数,其中nums1 是 nums2 的子集。

对于每个 0 <= i < nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums2 确定 nums2[j] 的 下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是 -1 。

返回一个长度为 nums1.length 的数组 **ans **作为答案,满足 **ans[i] **是如上所述的 下一个更大元素 。

输入:nums1 = [4,1,2], nums2 = [1,3,4,2].
输出:[-1,3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:
- 4 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1- 1 ,用加粗斜体标识,nums2 = [1,3,4,2]。下一个更大元素是 3- 2 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1

使用hashmap做映射,根据数值快速找到下标,还可以判断nums2[i]是否存在nums1中

接下来就要分析如下三种情况,一定要分析清楚。

情况一:当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况

此时满足递增栈(栈头到栈底的顺序),所以直接入栈。

情况二:当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况

如果相等的话,依然直接入栈,因为我们要求的是右边第一个比自己大的元素,而不是大于等于!

情况三:当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况

此时如果入栈就不满足递增栈了,这也是找到右边第一个比自己大的元素的时候。

判断栈顶元素是否在nums1里出现过,(注意栈里的元素是nums2的元素),如果出现过,开始记录结果。

class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        int[] reslut=new int[nums1.length];
        Arrays.fill(reslut,-1);
        Stack<Integer> stack=new Stack<>();
        HashMap<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<nums1.length;i++){
            map.put(nums1[i],i);
        }
        stack.add(0);

        for(int i=1;i<nums2.length;i++){
            if(nums2[i]<=nums2[stack.peek()]){
                stack.add(i);
            }else{
                while(!stack.isEmpty()&&nums2[stack.peek()]<nums2[i]){
                    if(map.containsKey(nums2[stack.peek()])){
                        Integer index=map.get(nums2[stack.peek()]);
                        reslut[index]=nums2[i];
                    }
                    stack.pop();
                }
                stack.add(i);
            }
        }
        return reslut;

    }
}

你可能感兴趣的:(算法,leetcode,java)