下一个更大元素

下一个更大元素1

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

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

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

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

示例 1:

输入: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 。

思路:使用单调栈,首先要想单调栈是从大到小还是从小到大。

在本题中:栈顶到栈底的顺序,要从小到大,也就是保持栈里的元素为递增顺序。只要保持递增,才能找到右边第一个比自己大的元素。

分析三种情况:

  • 当前遍历的元素nums2[i]小于栈顶元素nums2[stack.peek()]的情况,此时满足递增栈(栈头到栈底的顺序),所以直接入栈。
  • 当前遍历的元素nums2[i]等于栈顶元素nums2[stack.peek()]的情况,如果相等的话,依然直接入栈,因为要求的是右边第一个比自己大的元素,而不是大于等于!
  • 当前遍历的元素nums2[i]大于栈顶元素nums2[stack.peek()]的情况,此时如果入栈就不满足递增栈了,这也是找到右边第一个比自己大的元素的时候。需要判断栈顶元素是否在nums1里出现过,(注意栈里的元素是nums2的索引下标),如果出现过,开始记录结果。
class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        int len1 = nums1.length, len2 = nums2.length;
        int[] res = new int[len1];
        Arrays.fill(res, -1);
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < len1; i++) {
            map.put(nums1[i], i);//key为nums1[i],value为其下标
        }
        //从栈顶到栈底为递增,也就是说,栈底的元素最大
        Stack<Integer> stack = new Stack<>();
        stack.push(0);
        for (int i = 1; i < len2; i++) {
            if (nums2[stack.peek()] > nums2[i]) {//栈顶元素大于当前元素,则压入栈
                stack.push(i);
            } else {//栈顶元素小于当前元素
                while (!stack.isEmpty() && nums2[stack.peek()] < nums2[i]) {
                    //若栈顶元素在nums1数组中,则根据该元素得到其在nums1中的坐标,且该位置上的返回值应为nums2[i]
                    if (map.containsKey(nums2[stack.peek()])) {
                        int index = map.get(nums2[stack.peek()]);
                        res[index] = nums2[i];
                    }
                    stack.pop();//栈顶元素弹出栈
                }
                stack.push(i);//直到stack为空,或栈顶元素大于nums2[i],将其压入栈
            }
        }
        return res;
    }
}

下一个更大元素2

给定一个循环数组 numsnums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素

数字 x下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1

示例 1:

输入: nums = [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数; 
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。
class Solution {
    public int[] nextGreaterElements(int[] nums) {
        int len = nums.length;
        int[] res = new int[len];
        Arrays.fill(res, -1);
        Stack<Integer> stack = new Stack<>();
        stack.push(0);
        for (int i = 1; i < 2 * len; i++) {//遍历两边数组即可
            while (!stack.isEmpty() && nums[stack.peek()] < nums[i % len]) {
                res[stack.peek()] = nums[i % len];
                stack.pop();
            }
            stack.push(i % len);
        }
        return res;
    }
}
posted @ 2022-05-21 12:02  Arthurma  阅读(35)  评论(0编辑  收藏  举报