当前位置: 首页 > article >正文

单调栈题目

单调栈题目

  • 下一个更大元素
  • 每日温度
  • 下一个更大元素2
  • 链表中的下一个更大节点
  • 队列中可以看到的人数

单调栈用途不太广泛,只处理一类典型的问题,比如「下一个更大元素」,「上一个更小元素」等

下一个更大元素

下一个更大元素
在这里插入图片描述
思路:

这个问题可以这样抽象思考:把数组的元素想象成并列站立的人,元素大小想象成人的身高。这些人面对你站成一列,如何求元素「2」的下一个更大元素呢?很简单,如果能够看到元素「2」,那么他后面可见的第一个人就是「2」的下一个更大元素,因为比「2」小的元素身高不够,都被「2」挡住了,第一个露出来的就是答案。

在这里插入图片描述

class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2){
        HashMap<Integer,Integer> map=new HashMap();
        Stack<Integer> stack=new Stack();
        //nums2从右向左进栈
        for(int i=nums2.length-1;i>=0;i--){
            int ele=nums2[i];
            while(!stack.isEmpty()&&ele>=stack.peek()){
                //矮个子起开
                stack.pop();
            }
            if(stack.isEmpty()){
                map.put(ele,-1);
            }else{
                map.put(ele,stack.peek());
            }
            stack.push(ele);
        }
        int size=nums1.length;
        int[] res=new int[size];
        for(int i=0;i<size;i++){
            res[i]=map.get(nums1[i]);
        }
        return res;
    }
}

每日温度

每日温度
在这里插入图片描述

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        Stack<Node> stack=new Stack();
        int size=temperatures.length;
        int[]res=new int[size];
        for(int i=size-1;i>=0;i--){
            int ele=temperatures[i];
            while(!stack.isEmpty()&&ele>=stack.peek().temper){
                //太矮了起开
                stack.pop();
            }
            if(stack.isEmpty()){
                res[i]=0;
            }else{
                res[i]=stack.peek().index-i;
            }
            stack.push(new Node(ele,i));
        }
        return res;
    }
}
class Node{
    int temper;
    int index;
    Node(int temper,int index){
        this.temper=temper;
        this.index=index;
    }
}

下一个更大元素2

下一个更大元素2
在这里插入图片描述

class Solution {
    public int[] nextGreaterElements(int[] nums) {
        //循环数组,直接将数组翻两倍
        int size=nums.length;
        int[]res=new int[size];
        Stack<Integer> stack=new Stack();
        for(int i=2*size-1;i>=0;i--){
            int ele=nums[i%size];
            while(!stack.isEmpty()&&ele>=stack.peek()){
                //太矮了起开
                stack.pop();
            }
            if(i<size){
                if(stack.isEmpty()){
                    res[i]=-1;
                }else{
                    res[i]=stack.peek();
                }
            }
            stack.push(ele);
        }
        return res;
    }
}

链表中的下一个更大节点

链表中的下一个更大节点
在这里插入图片描述

先把链表换成数组,因为进栈的顺序是从后往前。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public int[] nextLargerNodes(ListNode head) {
        ListNode cur=head;
        ArrayList<Integer> arr=new ArrayList();
        while(cur!=null){
            arr.add(cur.val);
            cur=cur.next;
        }
        int size=arr.size();
        int[]res=new int[size];
        Stack<Integer> stack=new Stack();
        for(int i=size-1;i>=0;i--){
            int ele=arr.get(i);
            while(!stack.isEmpty()&&ele>=stack.peek()){
                //太矮了起开
                stack.pop();
            }
            if(stack.isEmpty()){
                res[i]=0;
            }else{
                res[i]=stack.peek();
            }
            stack.push(ele);
        }
        return res;
    }
}

队列中可以看到的人数

题目在这里插入图片描述

class Solution {
    //思路:从右往左进栈,个子高的在栈底,遇到个子矮的挤出去,并记录个数,进栈之前算好结果
    public int[] canSeePersonsCount(int[] heights) {
        int size=heights.length;
        int[]res=new int[size];
        Stack<Integer> stack=new Stack();
        int count=0;
        for(int i=size-1;i>=0;i--){
            int ele=heights[i];
            count=0;
            while(!stack.isEmpty()&&ele>=stack.peek()){
                //太矮了
                stack.pop();
                count++;//把ele右边矮子挤出去count个
            }
            if(stack.isEmpty()){
                res[i]=count;
            }else{
                res[i]=count+1;
            }
            stack.push(ele);
        }
        return res;
    }
}

http://www.kler.cn/a/537898.html

相关文章:

  • xss闯关
  • Spring Boot 的问题:“由于无须配置,报错时很难定位”,该怎么解决?
  • 使用 Apache Spark 进行大数据分析
  • CUDA Graph
  • [LeetCode]day16 242.有效的字母异位词
  • LIMO:少即是多的推理
  • 如何让虚拟机联上网
  • windows通过网络向Ubuntu发送文件/目录
  • 在大型语言模型(LLM)框架内Transformer架构与混合专家(MoE)策略的概念整合
  • 算法基础——容错
  • 蛋糕商城 Rust 版介绍二
  • 网络安全 | 保护智能家居和企业IoT设备的安全策略
  • 【AI】通过修改用户环境变量优化Ollama模型加载与访问
  • 计算机视觉-拟合
  • 聚焦 AUTO TECH China 2025,共探汽车内外饰新未来
  • 21.命令模式(Command Pattern)
  • FlinkCDC适配KADB失败实践
  • 学习 PostgreSQL 流复制
  • 背包问题常见bug
  • Qt—libpng warning: iCCP: known incorrect sRGB profile
  • Linux——网络(http)
  • 绿虫无人机3D光伏设计
  • 解决_ssl.so: cannot open shared object file: No such file or directory
  • 开源像素字体,可用于独立游戏开发
  • 通过k8s请求selfsubjectrulesreviews查询权限
  • Formality:时序变换(五)(寄存器复制)