【LeetCode热题100】打卡第35天:最小栈相交链表

news2024/12/23 14:49:23

文章目录

  • 【LeetCode热题100】打卡第35天:最小栈&相交链表
    • ⛅前言
  • 最小栈
    • 🔒题目
    • 🔑题解
  • 相交链表
    • 🔒题目
    • 🔑题解

【LeetCode热题100】打卡第35天:最小栈&相交链表

⛅前言

大家好,我是知识汲取者,欢迎来到我的LeetCode热题100刷题专栏!

精选 100 道力扣(LeetCode)上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,熟练掌握这 100 道题,你就已经具备了在代码世界通行的基本能力。在此专栏中,我们将会涵盖各种类型的算法题目,包括但不限于数组、链表、树、字典树、图、排序、搜索、动态规划等等,并会提供详细的解题思路以及Java代码实现。如果你也想刷题,不断提升自己,就请加入我们吧!QQ群号:827302436。我们共同监督打卡,一起学习,一起进步。

博客主页💖:知识汲取者的博客

LeetCode热题100专栏🚀:LeetCode热题100

Gitee地址📁:知识汲取者 (aghp) - Gitee.com

题目来源📢:LeetCode 热题 100 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台

PS:作者水平有限,如有错误或描述不当的地方,恳请及时告诉作者,作者将不胜感激

最小栈

🔒题目

原题链接:155.最小栈

image-20230711093221216

🔑题解

  • 解法一:使用两个栈

    这个方式是真的巧妙,这次算是开眼界了。现在就让我来讲解一下这个思路的具体实现方式吧(●ˇ∀ˇ●)

    首先我们要创建两个栈,一个 stack,一个minStack,stack是存储真实数据的栈,对外界是透明的,minStack是存储当前最小值的,对外界是不透明的。每次存储数据,stack是直接存,但是minStack是存储当前最小值,也就是要将要存储的值与minStack的栈顶元素进行比较,选较小值存,这样我们调用getMin时,直接返回minStack的栈顶元素即可

    image-20230711100418398

    /**
     * @author ghp
     * @title
     * @description
     */
    class MinStack {
    
        Deque<Integer> stack;
        Deque<Integer> minStack;
    
        public MinStack() {
            this.stack = new LinkedList<>();
            minStack = new LinkedList<>();
            // 初始化,防止出现NPE
            minStack.push(Integer.MAX_VALUE);
        }
    
        public void push(int val) {
            stack.push(val);
            minStack.push(Math.min(minStack.peek(), val));
        }
    
        public void pop() {
            stack.pop();
            minStack.pop();
        }
    
        public int top() {
            return stack.peek();
        }
    
        public int getMin() {
            return minStack.peek();
        }
    }
    

    复杂度分析:

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

    其中 n n n 为栈中元素的个数

拓展:为什么一般栈使用Deque而不是Stack?

这就需要考虑到两者的底层实现了,算法中一般使用Deque(双端队列)而不是Stack(栈)的主要原因如下:

  1. Stack是Java集合框架中提供的一种特殊数据结构,仅限于在栈顶进行元素的插入和删除操作,而Deque具有更加丰富的操作方法,可以在队首和队尾进行元素的插入、删除和检索。
  2. Stack类在Java中继承自Vector类,并且Stack类的方法都是同步的。因此,在并发环境下使用Stack可能会带来性能上的开销。而Deque的实现类LinkedList不是同步的,可以更好地满足多线程环境下的需求。
  3. 在Java 6之后,Deque被引入到Java集合框架中,将Stack类推荐用Deque接口的实现类来代替,以便提高代码的可读性和一致性。

总结起来,使用Deque而不是Stack有助于代码的可读性和一致性,同时避免了可能的性能开销和线程安全问题。因此,在大多数情况下,建议使用Deque来实现栈数据结构。

  • 解法二:使用 一个栈 + 一个变量

    不得不感慨这种方法更加巧妙,栈这个数据结构简直可以玩出花了🤣

    image-20230711151144936

    class MinStack {
    
        private Deque<Integer> stack;
        private int min;
    
        public MinStack() {
            this.stack = new LinkedList<>();
            this.min = Integer.MAX_VALUE;
        }
    
        public void push(int val) {
            if (val <= min) {
                // 当前值是更小,更新最小值,并且将之前的最小值入栈
                // 当前值等于最小值时,也需要进行入栈,否则后面会出现NPE
                stack.push(min);
                min = val;
            }
            stack.push(val);
        }
    
        public void pop() {
            if (stack.pop() == min){
                // 栈顶元素等于最小值,则更新最小值
                min = stack.pop();
            }
        }
    
        public int top() {
            return stack.peek();
        }
    
        public int getMin() {
            return min;
        }
    }
    

    复杂度分析:

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

    其中 n n n 为栈中元素的个数

相交链表

🔒题目

原题链接:160.相交链表

image-20230711141805585

🔑题解

  • 解法一:哈希表

    public class Solution {
        public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
            Set<ListNode> set = new HashSet<>();
            // 将链表A的所有节点存入Set集合中
            while (headA != null){
                set.add(headA);
                headA = headA.next;
            }
            // 找出链表B和链表A的共有节点
            while (headB != null){
                if (set.contains(headB)){
                    // 链表B的节点在链表A中也出现了,说明两者相交了
                    return headB;
                }
                headB = headB.next;
            }
            return null;
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n + m ) O(n+m) O(n+m)
    • 空间复杂度: O ( n ) O(n) O(n)

    其中 n n n 为链表A的节点个数, m m m为链表B的节点个数

  • 解法二:双指针

    双指针解法,是使用两个指针,遍历两遍链表,第一遍遍历让两个指针处于同一水平位置,第二遍遍历就可以直接找到交点了

    image-20230711202041886

    备注:红色代表第一次遍历,蓝色代表第二次遍历

    如果你一上来就来看这个方法,你可能会感觉优点不可思议,但事实如此。

    现在就让我们来证明一下:

    假设A链表的头节点a距离交点的距离为 p,B链表的头节点b距离交点 q,公共的长度为 t,则有一下推导

    1. 如果A和B不相交:

      ①A和B一样长,p=p.next, q=q.next,最终都为null

      ②A和B不一样长,A长B短,首先B走到终点,A和B走了q,然后B放到A的起点,A和B走了p,然后将A放到B的起点,循环往复,最后A走了 p+q、B走了 q+p ,A来到B的终点,B来到A的终点,最终都是null

    2. 如果A和B相交:

      ①A和B一样长,有 p=q,所以两者在 p(q)处相遇

      ②A和B不一样长,A长B短,首先B走到终点,A和B走了 q+t,B放到A的起点置0,此后再走p,此时B来到交点处,而A走了 q+t+p,而 t+p 表示A走到终点,要放到B链表的起点,但此时还剩 q 步,A从B的起点走 q 步,不正是交点处吗,所以两者走

      p+q+t 处时,两者在交点相遇

    当然我只是比较简单的推导了一下,如果想要看更加严格的数学证明,可以参考 Krahets 题解,链接附文末

    PS:这个推导十分类似于【LeetCode热题100】打卡第33天的题目环形链表II,这题我同样也是参考了 Krahets 的题解

    public class Solution {
        public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
            ListNode p = headA, q = headB;
            while (p != q) {
                p = p != null ? p.next : headB;
                q = q != null ? q.next : headA;
            }
            return p;
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n + m ) O(n+m) O(n+m)
    • 空间复杂度: O ( 1 ) O(1) O(1)

    其中 n n n 为链表A的节点个数, m m m为链表B的节点个数

    从这题我们也可以明白一个道理人生哲理:如果你和我有交点,走过你来时的路,我们终会相遇,如果你和我没有交点,走遍整个人生我们都不会相遇而是走向各自人生的终点null

参考题解

  • 详细通俗的思路分析,多解法 - 最小栈 - 力扣(LeetCode)
  • 160. 相交链表(双指针,清晰图解) - 相交链表 - 力扣(LeetCode)

在此致谢LeetCode哪些无私共享题解的Coder,也欢迎大家给他们点赞

最后,如果觉得本文对你有帮助,欢迎三连(点赞👍+评论✍+收藏⭐)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/744818.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL-分库分表详解(一)

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a; 小刘主页 ♥️努力不一定有回报&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️学习两年总结出的运维经验&#xff0c;以及思科模拟器全套网络实验教程。专栏&#xf…

C进阶:指针的进阶(1)

回归 哈喽哈喽大家好呀&#xff0c;我是灰灰快醒醒&#xff0c;时隔一个月又与大家见面了。众所周知&#xff0c;期末考试是中国教育部为大学生专门研发的一款开放式大逃杀游戏&#xff0c;学生需要扮演大难将至而绝望的人类&#xff0c;与小骚书共同完成《期末复习》的任务&a…

【无标题】采用技术外包做项目开发,不得不说的四大注意事项

在进行多项目开发及多个研发供应商团队管理&#xff08;技术外包管理&#xff09;时&#xff0c;你是不是也遇到不少问题。 项目管理者A&#xff1a;在项目开发中聘用外包技术团队的过程中&#xff0c;我踩过太多的坑&#xff0c;换过一批又一批的供应商&#xff0c;之前遇到过…

I.MX8MM系统构建 -- 1.系统烧录

硬件环境&#xff1a;米尔 MY8-C8MMX V1.3开发板软件工具&#xff1a;uuu烧录工具 环境准备 硬件环境 将开发板拨码开关调整为SW1(ON,OFF,x,x) SW2(x,x,x,x)&#xff0c;按照丝印字体方向向上为OFF&#xff0c;向下为ON。将开发板USB连接到PC给开发板通上12V电源(注意先修改拨…

Django框架之CSRF使用篇

Django框架之CSRF使用篇 目录 全局使用 设置csrf token 表单使用 脚本使用 单独豁免 引入csrf类库 设置单独豁免csrf 单独保护 关闭全局csrf 引入csrf库 设置函数保护 csrf token配置 总结 全局使用 Django项目配置中默认全局使用csrf中间件&#xff0c;注释掉即…

最新Jupyter Notebook(保姆级教程)

Jupyter Notebook介绍 什么是Jupyter Notebook Jupyter Notebook 是一个基于 Web 的交互式计算环境&#xff0c;支持多种编程语言&#xff0c;包括 Python、R、Julia 等。它的主要功能是将代码、文本、数学方程式、可视化和其他相关元素组合在一起&#xff0c;创建一个动态文…

STM32 Proteus仿真语音播报SGP30火灾报警器温度湿度-0072

STM32 Proteus仿真语音播报SGP30火灾报警器温度湿度-0072 Proteus仿真小实验&#xff1a; STM32 Proteus仿真语音播报SGP30火灾报警器温度湿度-0072 功能&#xff1a; 硬件组成&#xff1a;STM32F103C6单片机 0.960LED显示屏DHT11温度湿度电位器模拟SGP30二氧化碳传感器蜂鸣…

Layui实现动态树效果(书籍管理系统左侧下拉列表)

目录 一、前言 1.什么是树形菜单 2.树形菜单的使用场景 二、案例实现 1.需求分析 2.前期准备工作 ①导入依赖 ②工具类 BaseDao&#xff08;通用增删改查&#xff09; BuildTree(完成平级数据到父子级的转换) ResponseUtil&#xff08;将数据转换成json格式进行回显&…

1、Kubernetes 概述和架构

目录 一、基本介绍 二、kubernetes功能和架构 2.1、 概述 2.2 、功能 &#xff08;1&#xff09;自动装箱 &#xff08;2&#xff09;自我修复(自愈能力) &#xff08;3&#xff09;水平扩展 &#xff08;4&#xff09;服务发现 &#xff08;5&#xff09;滚动更新 &a…

磷铁环压脱机液压站比例阀放大器

冷轧热镀锌线液压系统比例阀放大器 热轧带钢步进梁式加热炉液压系统比例阀放大器 热轧带钢液压系统比例阀放大器 板坏连铸液压系统比例阀放大器 钢包精炼炉液压系统比例阀放大器 磷铁环压脱机液压站比例阀放大器 热轧带钢液压系统是一种用于热轧带钢生产的液压系统。它的…

校招失败后,在小公司熬了 2 年终于进了华为,竭尽全力....

其实两年前校招的时候就往华为投了一次简历&#xff0c;结果很明显凉了&#xff0c;随后这个理想就被暂时放下了&#xff0c;但是这个种子一直埋在心里这两年除了工作以外&#xff0c;也会坚持写博客&#xff0c;也因此结识了很多优秀的小伙伴&#xff0c;从他们身上学到了特别…

LiveGBS流媒体平台GB/T28181功能-支持UDP、TCP被动、TCP主动模式流传输模式之间有什么区别?

LiveGBS流媒体平台-国标流媒体服务几种流传输模式UDP、TCP被动、TCP主动模式区别是什么 1、背景1、GB28181流传输模式1.1、UDP1.2、TCP 被动1.3、TCP 主动 2、切换流传输模式2.1、编辑2.2、下拉切换 3、搭建GB28181视频直播平台 1、背景 国标GB28181协议中&#xff0c;视频流到…

什么是人工智能中的数据标注?

人工智能数据标注是对文本、视频、图像等元数据进行标注的过程&#xff0c;标记好的数据将用于训练机器学习的模型。常见的数据标注类型有文本标注、语义分割和图像视频标注。这些经标注的训练数据集可用于训练自动驾驶、聊天机器人、翻译系统、智能客服和搜索引擎等人工智能应…

LeetCode[239]滑动窗口最大值

难度&#xff1a;Hard 题目&#xff1a; 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例 1&#xff1a; 输入&#xf…

强化学习课程笔记一

强化学习基础概念及MDP算法&#xff0c;如图1所示 这张ppt上就展现了一节课全部的内容&#xff1a; Sets中有表示状态的S、有表示动作的A(s)、有表示奖励的R(s,a)&#xff0c;如图二所示 也介绍了概率分布&#xff08;Probability distribution&#xff09; 其中State transi…

2D组态:智慧生物质发电厂组态监控系统

进入21世纪以来&#xff0c;我国面临的能源安全和环境生态保护问题日趋严峻&#xff0c;可再生能源已经成为能源发展战略的重要组成部分以及能源转型的重要发展方向。根据可再生能源应用的不同领域&#xff0c;电力系统建设正在发生结构性转变&#xff0c;可再生能源发电已开始…

【技能实训】DMS数据挖掘项目-Day06

文章目录 任务6【任务6.5】编写物流数据分析类【任务6.6】创建物流数据分析测试类&#xff0c;测试任务6.5-6.6中的程序&#xff0c;演示物流信息的采集、分析及打印输出 任务6 【任务6.1】创建数据分析接口 在com.qst.dms.gather 下创建接口IDataAnalyse.java 【任务6.2】创…

【多线程进阶】多线程进阶学习(高并发、线程池、多线程使用场景)

文章目录 1、线程基础知识1.1、线程和进程线程和进程的区别&#xff1f; 1.2、并行与并发并行与并发有什么区别&#xff1f; 1.3、线程的创建方式创建线程的方式有哪些&#xff1f;刚才你说过&#xff0c;使用runnable和callable都可以创建线程&#xff0c;它们有什么区别呢&am…

MySQL数值

1.整数类型 TINYINT&#xff1a;非常小的整数&#xff0c;存储空间为1字节&#xff0c; 取值范围&#xff1a;有符号&#xff1a;-128---127&#xff0c;无符号&#xff1a;0---255 SMALLINT&#xff1a;小整数&#xff0c;存储空间为2字节 取值范围&#xff1a;有符号&#…

岩土工程振动在线监测:以道路桥梁基础为例

岩土工程振动在线监测&#xff1a;以道路桥梁基础为例 使用振弦传感器、采集仪和在线监测系统进行岩土工程监测&#xff1a;以道路桥梁基础振动监测为例 一个应用振弦传感器、振弦采集仪和在线监测系统构成的岩土工程监测案例是道路桥梁基础的振动监测。 在道路桥梁基础的振动…