力扣160 - 相交链表【双指针妙解】

news2024/10/6 10:30:48

链表也能相交~

  • 一、题目描述
  • 二、思路分析与罗列
  • 三、整体代码展示
  • 四、总结与提炼

一、题目描述

原题传送门
在这里插入图片描述

示例 1:
在这里插入图片描述

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at ‘8’
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,6,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
— 请注意相交节点的值不为 1,因为在链表 A 和链表 B 之中值为 1 的节点 (A 中第二个节点和 B 中第三个节点) 是不同的节点。换句话说,它们在内存中指向两个不同的位置,而链表 A 和链表 B 中值为 8 的节点 (A 中第三个节点,B 中第四个节点) 在内存中指向相同的位置。

示例 2:

在这里插入图片描述

输入:intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Intersected at ‘2’
解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [1,9,1,2,4],链表 B 为 [3,2,4]。
在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。

示例 3:
在这里插入图片描述

输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。
由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
这两个链表不相交,因此返回 null 。

提示:

  • listA 中节点数目为 m
  • listB 中节点数目为 n
  • 1 <= m, n <= 3 * 104
  • 1 <= Node.val <= 105
  • 0 <= skipA <= m
  • 0 <= skipB <= n
  • 如果 listA 和 listB 没有交点,intersectVal 为 0
  • 如果 listA 和 listB 有交点,intersectVal == listA[skipA] == listB[skipB]

看完了上面这些题目的描述,相信很多同学都被此题吓住了,觉得这个题目很难,自己做不出来,但是进到原题中可以看到这是一道力扣上的简单题,正确率也不低,有65%左右,所以不要害怕,我带你来慢慢分析一下,如何去求解本题⌛️

二、思路分析与罗列

  • 让我猜猜,若是没有题目给出的图示你是不是认为两个相交的链表应该是这样的😃
  • 哈哈,其实我也有想到过,但是后来一想这个只是单链表,到结点的相交处怎么指向后面的两个方向呢,所以果断丢弃了这个思想

在这里插入图片描述

  • 就像下面这样,因为交点处的结点时只有一个next,两个相交的链表只是一个普通的单链表,因此是不会存在下面这种结构的

在这里插入图片描述

  • 但是呢,实际上它是这样的,呈现一个【Y】字形

在这里插入图片描述

  • 以上这些是我在没看本题前的一个思考过程,这个点其实也挺重要的,对于一道题目,每个人都有它自己的思考过程,也不是在一开始就会有思路。刷题的时候我们应该开动自己的大脑,把自己想到的画出来,试试看,行不行得通,若是行不通,就立马换其他思路,在这个思考的过程中,你对这道题也有了一个逐步的认识

  • 好了,废话不多说,我们正式开始分析本题的思路
  • 以下是我对于这一道题的思路罗列
    在这里插入图片描述

好,看完题目的描述,我们来分析一下去求解这道题目,

在这里插入图片描述

  • 首先我们从案例一可以看到,对于两个链表的相交,就是当两个链表向后遍历的时候会碰到重合的结点,我们可以根据这个特点先对链表做一个遍历。先看看他们是否相交

在这里插入图片描述

  • 我的思路是这样的:首先一点是不能动两个链表的头,采用【curA】和【curB】去代替遍历,遍历结束的条件就是这两个指针的next指向NULL。
  • 在他们都遍历结束后对两个指针进行一个判断,若是相同,则表示两个链表一定在某一处汇聚到一起了,若是不同则表示两个链表不相交。这就是第一步,我们来看看代码
ListNode* curA = headA, *curB = headB;      //遍历
int lenA = 0, lenB = 0;     //记录两个链表的长度
while(curA->next){
    lenA++;
    curA = curA->next;
}

while(curB->next){
    lenB++;
    curB = curB->next;
}

if(curA != curB)
    return NULL;        //若两个结点的地址不同,则表示不相交,return NULL
  • 可以看到在循环内部出现了【lenA】和【lenB】,这个是用来在遍历链表时记录这个链表的长度,我们后面马上会用到

  • 接着第二步,我们就要开始考虑如何去求这两个链表的交点,但是在这之前呢,还要做一步,就是求出较长的那个链表,因为我们无法知晓较长的那个链表是什么,因此在后面求交点时就不知道需要遍历多少次才能碰到交点,所以这个时候我作出一个假设
  • 假设链表A是长的那个,链表B是短的那个。但这始终是我们的假设,并不成立,所以此时需要使用到我上面求出的【lenA】和【lenB】,对他们作出一个比较,若是【lenB > lenA】,则表示我们的假设错误,更新一下长的链表和短的链表,若是【lenA > lenB】,则无需进行判断,表示我们假设成功,直接使用我们一开始假设好的就行。代码是这样的
ListNode* longer = headA, *shorter = headB;      //先假设链表A长于链表B
if(lenB > lenA){            //若是假设错误则交换
    longer = headB;
    shorter = headA;
}
  • 接着我们便求出了较长的那个链表,此时只需要求出两个链表的长度差,记为【gap】。然后让长的那一个链表先走【gap】步,就可以让两个链表在同一起跑线上了。代码如下
int gap = abs(lenA - lenB);        //求出两个链表的长度差
while(gap--)
    longer = longer->next;      //先让长的链表走gap步,使得两链表位于同一起跑线

在这里插入图片描述


  • 完成了前面两步,最后一步我们就可以从两个链表现在的起始位置开始遍历,然后判断他们在中途是否相交与一个结点,此时直接return 就是交点
while(longer != shorter)        //一同往后走,寻找两链表的交点(此时一定相交) 
{
    longer = longer->next;
    shorter = shorter->next;
}
return longer;

在这里插入图片描述

三、整体代码展示

展示一下整体的代码,不过还是自己去敲一遍比较好哦

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* curA = headA, *curB = headB;      //遍历
        int lenA = 0, lenB = 0;     //记录两个链表的长度
        while(curA->next){
            lenA++;
            curA = curA->next;
        }

        while(curB->next){
            lenB++;
            curB = curB->next;
        }

        if(curA != curB)
            return NULL;        //若两个结点的地址不同,则表示不相交,return NULL

        ListNode* longer = headA, *shorter = headB;      //先假设链表A长于链表B
        if(lenB > lenA){            //若是假设错误则交换
            longer = headB;
            shorter = headA;
        }
            
        int gap = abs(lenA - lenB);        //求出两个链表的长度差
        while(gap--)
            longer = longer->next;      //先让长的链表走gap步,使得两链表位于同一起跑线

        while(longer != shorter)        //一同往后走,寻找两链表的交点(此时一定相交) 
        {
            longer = longer->next;
            shorter = shorter->next;
        }
        return longer;
    }
};

四、总结与提炼

  • 最后我们来总结一下本文所介绍的内容,本文讲解的是一道力扣中有关求解两个链表的相交结点的题目,对于本题虽然看上去比较复杂,但是经过我们的一顿分析之后,你是不是觉得本题并不是很难,因为有了这么一个分析的过程,其实你已经开始思考了,随着一步步解决方案的罗列,也就有了思路,此时再将每一步的思路慢慢转化为代码,其实做题也没有那么难,难的只是这个分析的过程罢了😄

以上就是本文所要描述的所有内容,感谢您对本文的观看,如有疑问请于评论区留言或者私信我都可以🍀

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

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

相关文章

MySQL索引

索引索引的相关概念索引分类索引的底层数据结构及其原理主键索引&二级索引聚集和非聚集索引哈西索引&&自适应哈西索引索引和慢查询日志索引优化索引的相关概念 什么是索引&#xff1f;索引其实就是一个数据结构。当表中的数据量到达几十万甚至上百万的时候&#x…

每个 Flutter 开发者都应该知道的一些原则

“仅仅让代码起作用是不够的。有效的代码经常被严重破坏。仅满足于工作代码的程序员表现得不专业。他们可能担心没有时间改进代码的结构和设计,但我不同意。没有什么比糟糕的代码对开发项目产生更深远、更长期的影响了。” ― Robert C. Martin,Clean Code:敏捷软件工艺手册…

fpga nvme 寄存器

图1所示的NVMe多队列&#xff0c;每个队列支持64K命令&#xff0c;最多支持64K队列。这些队列的设计使得IO命令和对命令的处理不仅可以在同一处理器内核上运行&#xff0c;也可以充分利用多核处理器的并行处理能力。每个应用程序或线程可以有自己的独立队列&#xff0c;因此不需…

基于Nacos的注册中心与配置中心

基于Nacos的注册中心与配置中心 Nacos简介 概述 Nacos全称是动态命名和配置服务&#xff0c;Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos主要用于发现、配置和管理微服务。 什么是Nacos Nacos支持几乎所有主流类型的服务的发现、配置和…

同花顺_代码解析_技术指标_A

本文通过对同花顺中现成代码进行解析&#xff0c;用以了解同花顺相关策略设计的思想 目录 ABI AD ADL ADR ADTM ADVOL AMV ARBR ARMS ASI ATR ABI 绝对幅度指标 算法&#xff1a;上涨家数减去下跌家数所得的差的绝对值。 该指标只适用于大盘日线。 行号 1 aa…

题目7飞机票订票系统

题目7飞机票订票系统问题描述:某公司每天有10航班(航班号、价格)&#xff0c;每个航班的飞机&#xff0c;共有80个座位&#xff0c; 20排&#xff0c;每排4个位子。编号为A&#xff0c;BCD。如座位号:10D表示10排D座。 运行界面如下&#xff1a; 1)能从键盘录入订票信息:乘客的…

[Games 101] Lecture 13-16 Ray Tracing

Ray Tracing Why Ray Tracing 光栅化不能得到很好的全局光照效果 软阴影光线弹射超过一次&#xff08;间接光照&#xff09; 光栅化是一个快速的近似&#xff0c;但是质量较低 光线追踪是准确的&#xff0c;但是较慢 Rasterization: real-time, ray tracing: offline生成一帧…

狗屎一样的面试官,你遇到过几个?

做了几年软件开发&#xff0c;我们都或多或少面试过别人&#xff0c;或者被别人面试过。大家最常吐槽的就是面试造火箭&#xff0c;进厂拧螺丝。今天就来吐槽一下那些奇葩&#xff08;gou&#xff09;一样的面试官 A 那是在我刚工作1年的时候&#xff0c;出去面试前端开发。 那…

分布式开源存储架构Ceph概述

概述 k8s的后端存储中ceph应用较为广泛&#xff0c;当前的存储市场仍然是由一些行业巨头垄断&#xff0c;但在开源市场还是有一些不错的分布式存储&#xff0c;其中包括了Ceph、Swift、sheepdog、glusterfs等 什么是ceph&#xff1f; Ceph需要具有可靠性&#xff08;reliab…

C++11标准模板(STL)- 算法(std::partition_point)

定义于头文件 <algorithm> 算法库提供大量用途的函数&#xff08;例如查找、排序、计数、操作&#xff09;&#xff0c;它们在元素范围上操作。注意范围定义为 [first, last) &#xff0c;其中 last 指代要查询或修改的最后元素的后一个元素。 定位已划分范围的划分点 …

线上崩了?一招教你快速定位问题。

&#x1f44f; 背景 正浏览着下班后去哪家店撸串&#xff0c;结果隔壁组同事囧着脸过来问我&#xff1a;大哥&#xff0c;赶紧过去帮忙看个问题&#xff01;客户反馈很多次了&#xff0c;一直找不出问题出在哪里&#xff01;&#xff01;&#xff01; 我&#xff1a;能不能有…

利用WPS功能破解及本地恢复密码

利用WPS功能破解及本地恢复密码 认识WPS功能 ​ WPS&#xff08;Wi-Fi Protected Setup&#xff09;是Wi-Fi保护设置的英文缩写。WPS是由Wi-Fi联盟组织实施的认证项目&#xff0c;主要致力于简化无线局域网安装及安全性能的配置工作。WPS并不是一项新增的安全性能&#xff0c;它…

数据结构之链表(单链表)

文章目录前言一、链表二、链表的八种结构1.单向或者双向2.带头或者不带头&#xff08;头&#xff1a;哨兵位&#xff09;3.循环或者不循环三、单链表1.接口2.接口的实现1.开辟一个新的节点1.打印单链表2.头插3.尾插4.头删5.尾删6.单链表的查找7.在pos位置之前插入数据8.在pos位…

MySQL8.0概述及新特性

文章目录学习资料常见的数据库管理系统排名&#xff08;DBMS&#xff09;SQL的分类DDL&#xff1a;数据定义语言DML&#xff1a;数据操作语言DCL&#xff1a;数据控制语言MySQL8.0新特性性能优化默认字符集DDL的原子化计算列宽度属性窗口函数公用表表达式索引新特性支持降序索引…

面试了20+前端大厂,整理出的面试题

事件是什么&#xff1f;事件模型&#xff1f; 事件是用户操作网页时发生的交互动作&#xff0c;比如 click/move&#xff0c; 事件除了用户触发的动作外&#xff0c;还可以是文档加载&#xff0c;窗口滚动和大小调整。事件被封装成一个 event 对象&#xff0c;包含了该事件发生…

RabbitMQ Windows 安装、配置、使用 - 小白教程

1、配套文件 下载erlang&#xff1a;http://www.erlang.org/downloads/ 下载RabbitMQ&#xff1a;http://www.rabbitmq.com/download.html 2、RabbitMQ服务端代码是使用并发式语言Erlang编写的&#xff0c;安装Rabbit MQ的前提是安装Erlang&#xff0c;双击otp_win64_21.1.ex…

计算机毕业设计springboot+vue+elementUI汽车车辆充电桩管理系统

项目介绍 随着我国汽车行业的不断发展&#xff0c;电动汽车已经开始逐步的领导整个汽车行业&#xff0c;越来越多的人在追求环保和经济实惠的同时开始使用电动汽车&#xff0c;电动汽车和燃油汽车最大的而不同就是 需要充电&#xff0c;同时我国的基础充电桩也开始遍及了大多数…

Java 异常处理

目录 一、异常的基本概念 二 、为何需要异常处理 三 、异常的处理 四 、异常类的继承架构 五 、抛出异常 5.1、程序中抛出异常 5.2、指定方法抛出异常 六 、自定义异常 不管使用的那种语言进行程序设计&#xff0c;都会产生各种各样的错误。 Java 提供有强大的异常处理…

商业银行普惠金融可持续发展综合能力呈现梯队化,专项领域各有所长

易观分析&#xff1a;普惠金融有别于传统的金融体系&#xff0c;强调构建包容性、公平性的金融服务生态&#xff0c;商业银行提升可持续发展的综合能力需关注五个方面的因素&#xff1a;获客能力上以普惠客群的金融需求为锚点&#xff0c;增强银行服务生态的多样性&#xff0c;…

罗正雄:基于展开交替优化的盲超分算法DAN

SFFAI 90—超分辨率专题《罗正雄&#xff1a;基于展开交替优化的盲超分算法》 退化表达式为&#xff1a; 盲超分就是已知y&#xff0c;求x 这个求解过程可以表示为如下最优化问题&#xff1a;求出使得以下表达式最小的k和x值 盲超分存在的挑战 病态&#xff1a;退化过程会损…