Home
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 设计模式
  • JavaSE
  • JVM
  • JUC
  • Netty
  • CPP
  • QT
  • UE
  • Go
  • Gin
  • Gorm
  • HTML
  • CSS
  • JavaScript
  • vue2
  • TypeScript
  • vue3
  • react
  • Spring
  • SpringMVC
  • Mybatis
  • SpringBoot
  • SpringSecurity
  • SpringCloud
  • Mysql
  • Redis
  • 消息中间件
  • RPC
  • 分布式锁
  • 分布式事务
  • 个人博客
  • 弹幕视频平台
  • API网关
  • 售票系统
  • 消息推送平台
  • SaaS短链接系统
  • Linux
  • Docker
  • Git
GitHub (opens new window)
Home
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 设计模式
  • JavaSE
  • JVM
  • JUC
  • Netty
  • CPP
  • QT
  • UE
  • Go
  • Gin
  • Gorm
  • HTML
  • CSS
  • JavaScript
  • vue2
  • TypeScript
  • vue3
  • react
  • Spring
  • SpringMVC
  • Mybatis
  • SpringBoot
  • SpringSecurity
  • SpringCloud
  • Mysql
  • Redis
  • 消息中间件
  • RPC
  • 分布式锁
  • 分布式事务
  • 个人博客
  • 弹幕视频平台
  • API网关
  • 售票系统
  • 消息推送平台
  • SaaS短链接系统
  • Linux
  • Docker
  • Git
GitHub (opens new window)
  • 哈希表

  • 双指针

  • 数组

  • 字符串

  • 链表

  • 树

  • 回溯

  • 动态规划

  • 图

  • 二分查找

  • 贪心

  • 栈&队列

    • 单调栈
      • 84. 柱状图中最大的矩形
      • 496. 下一个更大元素 I
      • 503. 下一个更大元素 II
      • 739. 每日温度
      • 316. 去除重复字母
      • 853. 车队
      • 907. 子数组的最小值之和
      • 962. 最大宽度坡
      • 768. 最多能完成排序的块 II
      • 2104. 子数组范围和
      • 1856. 子数组最小乘积的最大值
    • 单调队列
    • 栈模拟
  • 堆

  • 位运算

  • 数据结构设计

  • rui的精选题单

  • 笔试真题

  • LeetCode周赛

  • ACM模式输入输出
  • 数学

  • 数据结构与算法
  • 栈&队列
Nreal
2023-11-30
目录

单调栈

# 84. 柱状图中最大的矩形 (opens new window)

class Solution {
    int[] heights;
    public int largestRectangleArea(int[] heights) {
        this.heights = heights;
        int ret = 0;
        Stack<Integer> stack = new Stack<>();
        stack.add(-1);
        for(int i=0;i<=heights.length;i++){
            while(getHeight(i)<getHeight(stack.peek())){
                int x = stack.pop();
                ret = Math.max(ret,getHeight(x)*(i-stack.peek()-1));
            }
            stack.add(i);
        }
        return ret;
    }
    int getHeight(int i){
        if(i==-1)
            return -1;
        else if(i==heights.length)
            return -1;
        else
            return heights[i];
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 496. 下一个更大元素 I (opens new window)

class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        int[] greater = findGreater(nums2);
        Map<Integer,Integer> map = new HashMap<>();
        for(int i=0;i<nums2.length;i++){
            map.put(nums2[i],greater[i]);
        }
        int[] res = new int[nums1.length];
        for(int i=0;i<nums1.length;i++){
            res[i] = map.get(nums1[i]);
        }
        return res;
    }
    // 寻找数组后面更大元素的下标
    int[] findGreater(int[] nums){
        int n = nums.length;
        int[] res = new int[n];
        Stack<Integer> stack = new Stack<>();
        for(int i=n-1;i>=0;i--){
            while(!stack.isEmpty() && stack.peek()<=nums[i]){
                stack.pop();
            }
            res[i] = stack.isEmpty()?-1:stack.peek();
            stack.push(nums[i]);
        }
        return res;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 503. 下一个更大元素 II (opens new window)

class Solution {
    public int[] nextGreaterElements(int[] nums) {
        int n = nums.length;
        int[] res = new int[n];
        Stack<Integer> stack = new Stack<>();
        for(int i=2*n-1;i>=0;i--){
            while(!stack.isEmpty() && stack.peek()<=nums[i%n]){
                stack.pop();
            }
            res[i%n] = stack.isEmpty()?-1:stack.peek();
            stack.push(nums[i%n]);
        }
        return res;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 739. 每日温度 (opens new window)

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int n = temperatures.length;
        int[] res = new int[n];
        Stack<Integer> stack = new Stack<>();
        for(int i=n-1;i>=0;i--){
            while(!stack.isEmpty() && temperatures[i]>=temperatures[stack.peek()]){
                stack.pop();
            }
            res[i] = stack.isEmpty()?0:(stack.peek()-i);
            stack.push(i);
        }
        return res;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 316. 去除重复字母 (opens new window)

1.去重

用一个bool数组记录栈中元素

2.字符串顺序不打乱

栈保证顺序

3.字典序最小

cnt数组,如果后面还有元素可以pop,没有就不能pop

class Solution {
    public String removeDuplicateLetters(String s) {
        Stack<Character> stack = new Stack<>();
        int[] cnt = new int[256]; // 记录字符串中字符的数量
        for(int i=0;i<s.length();i++){
            cnt[s.charAt(i)]++;
        } 
        boolean[] inStack = new boolean[256]; // 栈中不存在重复元素
        for(char c:s.toCharArray()){
            cnt[c]--;
            if(inStack[c])
                continue ;
            while(!stack.isEmpty() && stack.peek()>c){
                // 若之后没有栈顶元素,不要POP
                if(cnt[stack.peek()]==0)
                    break;
                // 还有可以pop,为了最小字典序
                inStack[stack.pop()] = false;
            }
            stack.push(c);
            inStack[c] = true;
        }
        StringBuilder sb = new StringBuilder();
        while(!stack.isEmpty()){
            sb.append(stack.pop());
        }
        return sb.reverse().toString();
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 853. 车队 (opens new window)

# 907. 子数组的最小值之和 (opens new window)

# 962. 最大宽度坡 (opens new window)

# 768. 最多能完成排序的块 II (opens new window)

# 2104. 子数组范围和 (opens new window)

# 1856. 子数组最小乘积的最大值 (opens new window)

贪心&堆
单调队列

← 贪心&堆 单调队列→

Theme by Vdoing | Copyright © 2021-2024
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式