day53【代码随想录】单调栈之每日温度、下一个更大元素 I、下一个更大元素 II

文章目录

  • 前言
  • 一、每日温度(力扣739)
  • 二、下一个更大元素 I(力扣496)
  • 三、下一个更大元素 II(力扣503)【环形数组】
    • 思路一
    • 思路二


前言

单调栈:栈内元素保证递增或递减的
1、每日温度
2、下一个更大元素 I
3、下一个更大元素 II


一、每日温度(力扣739)

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。
day53【代码随想录】单调栈之每日温度、下一个更大元素 I、下一个更大元素 II_第1张图片

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

  • 当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况
  • 当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况
  • 当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况
class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        Deque<Integer> stack = new LinkedList<>();
        stack.push(0);
        int[] res = new int[temperatures.length];
        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()]){
                    res[stack.peek()] = i-stack.peek();
                    stack.pop();
                }
                stack.push(i);
            } 
        }
         return res;
    }
}

在这里插入图片描述

二、下一个更大元素 I(力扣496)

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

给你两个 没有重复元素 的数组 nums1 和 nums2 ,下标从 0 开始计数,其中nums1 是 nums2 的子集。
day53【代码随想录】单调栈之每日温度、下一个更大元素 I、下一个更大元素 II_第2张图片
步骤:
1、先求出nums2[]数组的 res2【同每日温度中的res数组】
2、遍历nums1[]数组,在nums2数组当中找到值为 nums1[i] 的下标Index
3、找到该下标对应的res2值 res2[Index]
4、如果res2[Index] == 0 那么 res1[i] == -1
5、res2[Index]!=0 res1[i] = nums2[ res2[Index] +Index ];

【优化:可以使用map集合】

class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        Deque<Integer> stack = new LinkedList<>();
        stack.push(0);
        int[] resNum1 = new int[nums1.length];
        int[] resNum2 = new int[nums2.length];

        for(int j=1;j<nums2.length;j++){
            if(nums2[j]<=nums2[stack.peek()]){
                stack.push(j);
            }else{
                while(!stack.isEmpty() && nums2[j]>nums2[stack.peek()]){
                    resNum2[stack.peek()] = j-stack.peek();
                    stack.pop();
                }
                stack.push(j);
            }
        }
        for(int i=0;i<nums1.length;i++){
            int Index = findInNum2(nums1[i],nums2);
            if(resNum2[Index]==0){
                resNum1[i]=-1;
            }else{
                resNum1[i] = nums2[resNum2[Index]+Index];
            }
        }
        return resNum1;
    }
    public int findInNum2(int target,int[] nums2){
        for(int i=0;i<nums2.length;i++){
            if(target==nums2[i]){
                return i;
            }
        }
        return 0;
    }
}
class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        Deque<Integer> stack = new LinkedList<>();
        stack.push(0);
        int[] resNum1 = new int[nums1.length];
        Arrays.fill(resNum1,-1);
        HashMap<Integer,Integer> hashMap = new HashMap<>();
        for(int i=0;i<nums1.length;i++){
            hashMap.put(nums1[i],i);
        }
        for(int j=1;j<nums2.length;j++){
            if(nums2[j]<=nums2[stack.peek()]){
                stack.push(j);
            }else{
                while(!stack.isEmpty() && nums2[j]>nums2[stack.peek()]){
                    if(hashMap.containsKey(nums2[stack.peek()])){
                        Integer index = hashMap.get(nums2[stack.peek()]);
                        resNum1[index] = nums2[j];
                    }
                    stack.pop();
                }
                stack.push(j);
            }
        }
        return resNum1;
    }
}

在这里插入图片描述

三、下一个更大元素 II(力扣503)【环形数组】

给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。
day53【代码随想录】单调栈之每日温度、下一个更大元素 I、下一个更大元素 II_第3张图片

思路一

分析:
重新定义一个数组:
nums = [1,2,1]
nums2 = [1,2,1,1,2,1];
然后再去求res数组
最后res只取原数组长度即可

class Solution {
    public int[] nextGreaterElements(int[] nums) {
        //拼接
        int[] numsNew = new int[nums.length*2];
        for(int i=0;i<nums.length;i++){
            numsNew[i] = nums[i];
        }
        for(int i=nums.length;i<numsNew.length;i++){
            numsNew[i] = nums[i-nums.length];
        }

        int[] res = new int[nums.length*2];
        Arrays.fill(res,-1);
        Deque<Integer> stack = new LinkedList<>();
        stack.push(0);

        for(int i=1;i<numsNew.length;i++){
            if(numsNew[i]<= numsNew[stack.peek()]){
                stack.push(i);
            }else{
                while(!stack.isEmpty() && numsNew[i]>numsNew[stack.peek()]){
                    res[stack.peek()] = numsNew[i];
                    stack.pop();
                }
                stack.push(i);
            }
        }
        int[] newRes = new int[nums.length];
        for(int i=0;i<nums.length;i++){
            newRes[i] = res[i];
        }
        return newRes;
    }
}

相当于在空间复杂度上重新定义了一个二倍的数组长度
在这里插入图片描述

思路二

分析
在原数组的基础上模拟成环的过程【取模】

class Solution {
    public int[] nextGreaterElements(int[] nums) {
        int[] res = new int[nums.length];
        Arrays.fill(res,-1);
        Deque<Integer> stack = new LinkedList<>();
        stack.push(0);

        for(int i=1;i<nums.length*2;i++){
            if(nums[i%nums.length]<= nums[stack.peek()]){
                stack.push(i%nums.length);
            }else{
                while(!stack.isEmpty() && nums[i%nums.length]>nums[stack.peek()]){
                    res[stack.peek()] = nums[i%nums.length];
                    stack.pop();
                }
                stack.push(i%nums.length);
            }
        }
        return res;
    }
}

你可能感兴趣的:(代码随想录,算法,数据结构,leetcode,java)