🌕 503. 下一个更大元素 II

吞佛童子2022年6月20日
  • algorithm
  • stack
大约 2 分钟

🌕 503. 下一个更大元素 II

难度: 🌕

问题描述

img_21.png


解法 1 - Stack + HashMap

class Solution {
    public int[] nextGreaterElements(int[] nums) {
        // 思路:
        // 延长数组 == 2 * n - 1,这样最后一个元素肯定能包含进去- 循环情况下
        // 非严格递减栈 - 而且只放入符合范围的下标,超范的部分直接跳过
        // 因此 stack 中存储的是下标
        // 由于 数组中可能有重复元素,为防止发生相同值的覆盖,所以 map 中的 key 存放的也是下标
        int len = nums.length;
        int[] array = new int[2 * len - 1];
        System.arraycopy(nums, 0, array, 0, len);
        System.arraycopy(nums, 0, array, len, len - 1);
        LinkedList<Integer> stack = new LinkedList<>();
        HashMap<Integer, Integer> map = new HashMap<>();
        int size = array.length;
        for(int i = 0; i < size; i ++) {
            // System.out.println(" ------ " + array[i] + "  -----   ");
            // test(stack, array);
            if(stack.isEmpty()) {
                stack.push(i);
            } else {
                // stack 非空
                int tmp = array[stack.peek()];
                int cur = array[i];
                if(cur <= tmp) {
                    stack.push(i);
                } else {
                    // cur > tmp
                    while(!stack.isEmpty() && cur > array[stack.peek()]) {
                        int peekIndex = stack.pop();
                        if(peekIndex < len) {
                            // 只有在有效范围的下标才存入 map
                            map.put(peekIndex, cur);
                        }
                    }
                    stack.push(i);
                }
            }
        }
        // 遍历得到结果
        int[] res = new int[len];
        for(int i = 0; i < len; i ++) {
            if(!map.containsKey(i)) {
                res[i] = -1; // 没有符合条件的值
            } else {
                res[i] = map.get(i);
            }
        }
        return res;
    }

    private void test(LinkedList<Integer> list, int[] array) {
        for(int i = 0; i < list.size(); i ++) {
            System.out.print(array[list.get(i)] + "    ");
        }
        System.out.println();
    }
}

输出 1

img_20.png

解法 2 - 优化,有些没有必要存在

class Solution {
    public int[] nextGreaterElements(int[] nums) {
        // 思路:
        // 延长数组 == 2 * n - 1,这样最后一个元素肯定能包含进去- 循环情况下
        // 非严格递减栈 - 而且只放入符合范围的下标,超范的部分直接跳过
        // 因此 stack 中存储的是下标
        int len = nums.length;
        int[] array = new int[2 * len - 1];
        System.arraycopy(nums, 0, array, 0, len);
        System.arraycopy(nums, 0, array, len, len - 1);
        LinkedList<Integer> stack = new LinkedList<>();
        int size = array.length;
        int[] res = new int[len];
        Arrays.fill(res, -1); // 初始化 res
        for(int i = 0; i < size; i ++) {
            // System.out.println(" ------ " + array[i] + "  -----   ");
            // test(stack, array);
            if(stack.isEmpty()) {
                stack.push(i);
            } else {
                // stack 非空
                int tmp = array[stack.peek()];
                int cur = array[i];
                if(cur <= tmp) {
                    stack.push(i);
                } else {
                    // cur > tmp
                    while(!stack.isEmpty() && cur > array[stack.peek()]) {
                        int peekIndex = stack.pop();
                        if(peekIndex < len) {
                            // 只有在有效范围的下标才存入 map
                            res[peekIndex] = cur;
                        }
                    }
                    stack.push(i);
                }
            }
        }
        return res;
    }

    private void test(LinkedList<Integer> list, int[] array) {
        for(int i = 0; i < list.size(); i ++) {
            System.out.print(array[list.get(i)] + "    ");
        }
        System.out.println();
    }
}

输出

img_22.png

上次编辑于: 2022/10/10 下午8:43:48
贡献者: liuxianzhishou