【LeetCode】相交链表——面试经典题目

题目链接:力扣

b3e84f4666374d07b1f1312f529bdbcb.png

首先先声明一下这里的相交可不是如下图一样的相交

ae74043c4b954babba1050fb4a2e8bfb.png

这样相交是错误的,一个节点的指针域是不可能同时存放两份地址的。

这样的相交才是正确的

6410566f1b184d1d84d7076e14331b90.png

思路一:根据题目意思,我们要的是相交的起始节点,那么我们可以先遍历两个链表,得到这两个链表的长度,再用较长的链表减去较短的链表,得到一个差值(后面我就用gap来代替这个差值了),再让较长的链表先走gap步,走完后,较短的链表和较长的链表同时向后走,直到走到他们的下一个节点相等时停止,这一个节点就是它们的相交节点。

画图演示如下:

f02f22c41cca47499f9f2199f9bcc3d4.png

cddc24c2511f410d8f93ad17425de5c9.png

47d99ebd76ea434cadf0d4bf51dae9bf.png

d59f6728362a4c6aa292e609e8bc0096.png

 代码如下:

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
//判断链表是否为空可加可不加
if(headA==NULL||headB==NULL)
{
return NULL;
}
struct ListNode* curA=headA;
struct ListNode* curB=headB;
int lenA=1,lenB=1;
//计算链表的长度
while(curA->next)
{
    curA=curA->next;
    lenA++;
}
while(curB->next)
{
    curB=curB->next;
    lenB++;
}
//没有节点则返回NULL
if(curA!=curB)
{
    return NULL;
}
//求第一个交点
struct ListNode *shortlist=headA,*longlist=headB;//一个小技巧
if(lenA>lenB)
{
    shortlist=headB;
    longlist=headA;
}
//计算两个链表长的差值
//用abs计算绝对值,就不用考虑顺序问题
int gap=abs(lenA-lenB);
//长的先走gap步
while(gap--)
{
    longlist=longlist->next;
}
//找相同节点
while(shortlist!=longlist)
{
    shortlist=shortlist->next;
    longlist=longlist->next;
}
//返回longlist也是一样的
return shortlist;
}

思路二:定义两个指针, 第一轮让两个到达末尾的节点指向另一个链表的头部, 最后如果相遇则为交点(在第一轮移动中恰好抹除了长度差) 两个指针等于移动了相同的距离, 有交点就返回, 无交点就是各走了两条指针的长度。


class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
       
        if(headA == NULL || headB == NULL) return NULL;
        ListNode*curA = headA, *curB = headB;
        // 在这里第一轮体现在curA和curB第一次到达尾部会移向另一链表的表头, 而第二轮体现在如果curA或curB相交就返回交点, 不相交最后就是null==null
        while(curA != curB) {
            curA = curA == NULL ? headB : curA->next;
            curB = curB == NULL ? headA : curB->next;
        }
        return curA;
    }
};

这个思路不太好想,知道有这个就行

总结:数据结构的oj题就是要多画图才能分析出来,光想的话还是有点难的。

今天的题解就分享到这

觉得内容对你用的话,就给博主三连哦!!!

4a73dd9d700947f7b0a1398e9881b57e.gif

 

 

  • 12
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值