寻找相交链表的起始节点的双指针方法

本文介绍了使用双指针方法解决寻找两个单链表相交起始节点的问题。首先找到两个链表的尾结点并计算长度,比较尾结点地址判断是否相交。如果相交,通过调整指针长度差使其同步,然后同时遍历找到相交点;否则返回null。这种方法的时间复杂度为O(N+M),空间复杂度为O(1)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


题目描述:

给你两个单链表的头节点 headAheadB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null

图示两个链表在节点 c1 开始相交:

LeetCode:相交链表


方法:双指针

思路

  • 定义两个尾指针,遍历找到两个链表的尾结点,同时计算链表长度

  • 比较尾结点的地址,相同说明相交;不相同说明不相交

  • 如果相交,定义长指针先移动差距步,把长短指针置于同一位置

  • 然后遍历同时开始链表,第一个地址相等的结点,即为起始结点

​ 示意图:

代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) 
{
    struct ListNode* tailA = headA;
    struct ListNode* tailB = headB;
    int lenA = 1;
    int lenB = 1;

    //找到尾结点
    //遍历链表A,找尾结点,计算长度
    while(tailA->next)
    {
        tailA = tailA->next;
        lenA++; 
    }

    //遍历链表A,找尾结点,计算长度
    while(tailB->next)
    {
        tailB = tailB->next;
        lenB++; 
    }

    //比较两个尾结点的地址
    //链表相交
    if(tailA == tailB)
    {
    //找到起始结点
        int gap = abs(lenA-lenB);
        //找到长链表
        struct ListNode* longList = headA;
        struct ListNode* shortList = headB;

        if(lenA < lenB)
        {
            longList = headB;
            shortList = headA;
        }

        //把两个链表置于同一位置
        while(gap--)
        {
            longList = longList->next;
        }

        //两个链表从同一位置开始遍历
        while(longList != shortList)
        {
            longList = longList->next;
            shortList = shortList->next;
        }

        //返回起始结点
        return longList;
    }

    //链表不相交
    else
    {
        return false;
    }
}

复杂度分析

  • 时间复杂度:O(N+M),N是链表A结点总数,M是链表B结点总数,
    • 链表不相交,尾指针tailA和tailB各自遍历一次链表,O(N+M)
    • 链表相交
      • 两次找尾,O(N+M)
      • 找起始结点,最坏情况,在尾结点相交,O(N+M)
  • 空间复杂度:O(1),函数getIntersectionNode运行过程中,只开辟了常数个变量空间,没有额外再开辟空间

总结

  • 本文介绍了一种使用双指针方法来寻找两个单链表相交的起始节点的解决方案。
  • 通过定义两个尾指针,遍历找到两个链表的尾结点,并同时计算链表的长度。
  • 然后比较尾结点的地址,如果相同则说明链表相交,接下来将长指针先移动差距步,使得两个链表的指针处于相同位置,
  • 然后同时遍历两个链表并找到第一个地址相等的节点,该节点即为相交链表的起始节点。
  • 如果尾结点的地址不相同,则说明两个链表不相交。
  • 该方法的时间复杂度为O(N+M),其中N和M分别是两个链表的结点总数。并且该方法的空间复杂度为O(1)。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值