相交链表(C语言)

【题目描述】
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

题目及图片来源(力扣):相交链表
示例1示例3

注:
题目数据保证整个链式结构中不存在环
函数返回结果后,链表必须保持其原始结构

【基本思路】
先看比较特殊的情况,两个链表相交且长度相等(比如示例1的图去掉B左边的第一个节点)。这时只要双指针同时从各自的链表头开始向后走,等到两指针相等时便是相交的起始节点

再看比较一般的情况,两个链表相交但长度不等(如示例1图)。这时我们想:如果能把长度差消除掉,不就回归上面的特殊情况了吗?那么有办法消除长度差吗?答案是有的:分别计算两个单链表的长度,然后取其差值,让长链表的节点指针从头开始先向后走差值个节点,然后和短链表的节点指针(它从短链表的头开始走)同时向后走,等到两指针相等时便是相交的起始节点。

那么如果两个链表不相交呢?这种情况如何处理?其实步骤跟上面的情况一样,只是最后的“相交节点”是 null 罢了(可以认为 null 是特殊的“相交节点”)。

【代码实现】

typedef struct ListNode ListNode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    //分别对两个单链表计算长度
    int lenA = 0, lenB = 0;
    ListNode* curA = headA, *curB = headB;
    while(curA)
    {
        ++lenA;
        curA = curA->next;
    }
    while(curB)
    {
        ++lenB;
        curB = curB->next;
    }
    //两个单链表长度差
    int gap = abs(lenA - lenB);
    //先假设链表A更长
    ListNode* longList = headA;  
    ListNode* shortList = headB;
    if(lenA < lenB)  // 如果链表B更长,就换过来
    {
        longList = headB;
        shortList = headA;
    }
    //消除长度差
    while(gap--)
    {
        longList = longList->next;
    }
    //双指针同时向后走
    while(longList != shortList)
    {
        longList = longList->next;
        shortList = shortList->next;
    }
    //如果两者相等,则返回相交的起始节点(如果链表不相交,则返回空指针)
    return longList;
}

复杂度分析:
时间复杂度:O(M + N),其中 M 和 N 分别为两链表的长度。
空间复杂度:O(1)。

别人想出了另一种解法,相对来说没那么好想,不过其代码很简洁。
别人的另一种解法(含清晰图解)

本专栏
有关链表的题目

其它专栏
有关数组的题目

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值