随想录训练营Day59 | DP - - 503.下一个更大元素II

91 阅读1分钟

随想录训练营Day59 | DP - - 503.下一个更大元素II

标签: LeetCode闯关记


503.下一个更大元素II

key:cf739. 每日温度,区别在于循环数组,需要for循环两次

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<>();//存的是元素下标
        for (int i = 0; i < 2*len; i++) {//循环数组,所以直接遍历两次解决问题
            while(!stack.isEmpty() && nums[i%len] > nums[stack.peek()]){
                res[stack.peek()] = nums[i%len];//变化:nums[i%len]
                stack.pop();
            }
            stack.push(i%len);
        }
        return res;
    }
}

42. 接雨水

很玄妙的解法
横向求解: 栈顶和栈顶的下一个元素以及要入栈的元素,三个元素来接水! img_9.png

class Solution {
    public int trap(int[] height) {
        int res = 0;
        Stack<Integer> stack = new Stack<>();
        stack.push(0);
        int mid = 0;
        int width = 0;
        int hght = 0;
        for (int i = 1; i < height.length; i++) {
            //分三种情况 > < = 是为了提高效率,因为考虑遇到相同高度的柱子: 遇到相同的元素,更新栈内下标,就是将栈里元素(旧下标)弹出,将新元素(新下标)加入栈中。这样可以减少无效计算
//            if(height[i] < height[stack.peek()]){
//                stack.push(i);
//            }else if (height[i] == height[stack.peek()]){
//                stack.pop();
//                stack.push(i);
//            }else{
                while (!stack.isEmpty() && height[i] > height[stack.peek()]){
                    mid = stack.peek();
                    stack.pop();
                    if(!stack.isEmpty()){//这个判断重要
                        hght = Math.min(height[i], height[stack.peek()]) - height[mid];
                        width = i- stack.peek() - 1;
                        //System.out.println("hgt=" + hght + " width=" + width);
                        res += hght * width;
                        //System.out.println(res);
                    }

                }
            }
            stack.push(i);
        }
        return res;
    }
}