题目
给你两个单链表的头节点
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,所以没有讨论空链表的情况。