力扣160. 相交链表

题目

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。题目数据保证整个链式结构中不存在环。

注意,函数返回结果后,链表必须保持其原始结构

链接:160. 相交链表 - 力扣(LeetCode)

题解

判断两个单链表是否相交,只能通过依次比较结点的地址来判断,不能通过结点的值判断。首先,我们应该明确如果两个单链表相交,那么这两个链表的形状只能是Y字型,不能是X字型,如果是X字型,则相交结点有两个后继结点,而单链表结点只能有一个后继结点。因此可得出,若两个单链表相交,则两个链表的尾结点的地址一定相同;若两个链表的尾结点的地址不相同,则两个单链表一定不相交

所以程序可以先判断两个链表尾结点的地址是否相同,若不同返回NULL;若相同则找相交结点。寻找相交结点的方法如下:

假设两个单链表的长度分别为lenA和lenB,设置两个指针分别指向两个链表的头结点,让指向较长链表的指针先走abs(lenA-lenB)步,然后两个指针再同时向后走,边走边比较指针所指结点的地址是否相等,若相等则返回当前结点,若不等则同时向后走一步,直到找到第一个相交结点为止。

代码如下:

struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB) 
{
    struct ListNode* tailA = headA;
    struct ListNode* tailB = headB;
    int lenA = 1;
    int lenB = 1;
    while (tailA->next)
    {
        tailA = tailA->next;
        lenA++;
    }
    while (tailB->next)
    {
        tailB = tailB->next;
        lenB++;
    }
    if (tailA != tailB)
        return NULL;

    struct ListNode* longList = headA;
    struct ListNode* shortList = headB;
    if (lenA < lenB)
    {
        longList = headB;
        shortList = headA;
    }
    int gap = abs(lenA - lenB);
    while (gap--)
    {
        longList = longList->next;
    }
    while (longList != shortList)
    {
        longList = longList->next;
        shortList = shortList->next;
    }
    return longList;
}

注意,因为题目中说明链表中结点个数大于等于1,所以没有讨论空链表的情况。

猜你喜欢

转载自blog.csdn.net/minLi_/article/details/131752782