代码随想录二刷第十一天 | 739. 每日温度、496.下一个更大元素I、503.下一个更大元素II、42. 接雨水、84.柱状图中最大的矩形

63 阅读2分钟

739. 每日温度

题目:739. 每日温度 - 力扣(LeetCode)

题解:代码随想录

状态:AC

思路

单调栈基础题

代码

时间复杂度:O(n) 空间复杂度:O(n)

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        Stack<Integer> stack = new Stack<>();
        int[] res = new int[temperatures.length];
        for (int i = 0; i < temperatures.length; i++) {
            while (!stack.isEmpty() && temperatures[stack.peek()] < temperatures[i]) {
                int temp = stack.pop();
                res[temp] = i - temp;
            }
            stack.push(i);
        }
        return res;
    }
}

496.下一个更大元素 I

题目:496. 下一个更大元素 I - 力扣(LeetCode)

题解:代码随想录

状态:半AC

思路

单调栈套壳,加上了hashMap索引一下,只是比每日温度多了一步操作。

代码

时间复杂度:O(n) 空间复杂度:O(n)

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

        Stack<Integer> stack = new Stack<>();
        for(int i = 0; i < nums2.length; i++){
            while(!stack.isEmpty() && nums2[stack.peek()] < nums2[i]){
                int temp = stack.pop();
                if(map.containsKey(nums2[temp])){
                    res[map.get(nums2[temp])] = nums2[i];
                }
            }
            stack.push(i);
        }

        return res;
    }
}

503.下一个更大元素II

题目:503. 下一个更大元素 II - 力扣(LeetCode)

题解:代码随想录

状态:AC

思路

简单直接的思路:直接将数组nums变成nums + nums,拼接一下即可。但时间复杂度和空间复杂度都比较高。

进阶思路:可以模拟遍历两遍nums,以此提升性能

代码

时间复杂度:O(n) 空间复杂度:O(n)

class Solution {
    public int[] nextGreaterElements(int[] nums) {
        int n = nums.length;
        int[] res = new int[n];
        Arrays.fill(res, -1);
        
        Stack<Integer> stack = new Stack<>();
        for(int i = 0; i < 2 * n; i++){
            int idx = i >= n ? i - n : i;
            while(!stack.isEmpty() && nums[stack.peek()] < nums[idx]){
                int temp = stack.pop();
                res[temp] = nums[idx];
            }
            stack.push(idx);
        }

        return res;
    }
}

42. 接雨水

题目:42. 接雨水 - 力扣(LeetCode)

题解:代码随想录

状态:需要多复习

思路

单调栈。但需要注意:

  1. 注意最左侧坐标轴不能算墙
  2. 高度计算公式:当前柱子两侧较低的一侧的高度,减去当前柱子的高度,比如3,1,2中h=2-1=1
  3. 宽度计算公式:柱子左右的宽度right-left-1

代码

时间复杂度:O(n) 空间复杂度:O(n)

class Solution {
    public int trap(int[] height) {
        int res = 0;
        Stack<Integer> stack = new Stack<>();
        for (int i = 0; i < height.length; i++) {
            while (!stack.isEmpty() && height[stack.peek()] < height[i]) {
                int temp = stack.pop();
                if (!stack.isEmpty()) {
                    int h = Math.min(height[i], height[stack.peek()]) - height[temp];
                    int w = i - stack.peek() - 1;
                    res += h * w;
                }
            }
            stack.push(i);
        }
        return res;
    }
}

84.柱状图中最大的矩形

题目:84. 柱状图中最大的矩形 - 力扣(LeetCode)

题解:代码随想录

状态:需要多复习

思路

在接雨水的基础上,做出如下改动:

  • 数组前后补0
  • 单调栈中元素顺序,栈头为栈中最大元素
  • 结果是求面积最大值

代码

时间复杂度:O(n) 空间复杂度:O(n)

class Solution {
    public int largestRectangleArea(int[] heights) {
        int[] newHeight = new int[heights.length + 2];
        System.arraycopy(heights, 0, newHeight, 1, heights.length);
        newHeight[heights.length+1] = 0;
        newHeight[0] = 0;
        int res = 0;
        Stack<Integer> stack = new Stack<>();
        for(int i = 0; i < newHeight.length; i++){
            while(!stack.isEmpty() && newHeight[stack.peek()] > newHeight[i]){
                int temp = stack.pop();
                int h = newHeight[temp];
                int w = i - stack.peek() - 1;
                res = Math.max(h * w, res);
            }
            stack.push(i);
        }
        return res;
    }
}