力扣160 - 相交链表【双指针妙解】
创始人
2024-01-29 17:12:40
0

链表也能相交~

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

一、题目描述

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

示例 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 NULLListNode* longer = headA, *shorter = headB;      //先假设链表A长于链表Bif(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;}
};

四、总结与提炼

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

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

相关内容

热门资讯

小吃创业项目小本创业者的好小吃... 现在的小吃市场,相继出现很多的小吃品种,既好吃,价格又便宜,得到了很多顾客的青睐,市场极为火爆,因此...
【贵州贵州创业小本项目创业好项... 为什么穷人多不敢去创业蛋糕创业蛋糕店创业30岁女人创业做什么适合女性创业的大学生适合什么创业毕业生如...
贵州黔东南小本创业项目优选无醇... 贵州黔东南小本创业项目优选无醇酒碗灶供应厂家npx9贵州黔东南小本创业项目优选无醇酒碗灶供应厂家现在...
最新适合中小城市的六个小本生意... 最适合中小城市的小本生意2:绿色早餐配送现在经济发展社会稳定,人们必然越来越重视健康,且认识到早餐与...
适合小城市做的小本创业小城市小... 当下的人们生活中对个性化的一些物品越来越喜欢,尤其是生活中日常值得留念的照片,存的太多了没处保存,时...
投资小本创业开店项目加盟 投资... ♥♥♥盒饭加盟♥♥♥现在人们生活的节奏很快,每天进出写字楼的人们都是步履匆匆,快节奏的生活让中午外出...
九**小本创业开店项目 九**... 首页企业动态餐饮文章详情非常不错的9个初次小本创业项目推荐!时间:2017-07-浏览:1421随着...
最有潜力的9个小本创业项目 适... 说起创业,很多人都会把目标放在城市,觉得城市消费水平高,受众多,但你只考虑到了一方面,从另一方面来说...
一千元投资创业好项目 一千元创... 适合一千元投资创业项目有哪些呢?目前很多的小本创业者都想做点小本创业者,一千元投资创业是很多小本创业...
西安警方通报:“民警违停车辆致...   7月9日凌晨,西安警方发布情况通报: