题目描述:
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
图示两个链表在节点 c1 开始相交:
方法一:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* getIntersectionNode(ListNode* headA, ListNode* headB) {
int la = 0;
int lb = 0;
ListNode* dummynodea = new ListNode(0);
ListNode* dummynodeb = new ListNode(0);
dummynodea->next = headA;
dummynodeb->next = headB;
ListNode* tempa = dummynodea;
ListNode* tempb = dummynodeb;
while (tempa != nullptr)
{
tempa = tempa->next;
la++; //计算链表a的长度
}
while (tempb != nullptr)
{
tempb = tempb->next;
lb++; //计算链表b的长度
}
tempa = dummynodea;
tempb = dummynodeb;
while (la > lb)
{
tempa = tempa->next;
la--;
}
while (lb > la)
{
tempb = tempb->next;
lb--;
}
for (int i = 0; i < la; i++)
{
if (tempa->next == tempb->next)
{
return tempa->next;
}
tempa = tempa->next;
tempb = tempb->next;
}
return nullptr;
}
};
一时想不到什么好方法,只能计算出链表a和链表b各自的长度,然后在两条链表的相同长度的结点出发寻找tempa和tempb的下一结点是否为同一结点。
方法二:
class Solution {
public:
ListNode* getIntersectionNode(ListNode* headA, ListNode* headB) {
ListNode* nodea = headA;
ListNode* nodeb = headB;
while (nodea != nodeb)
{
nodea = nodea == nullptr ? headB : nodea->next;
nodeb = nodeb == nullptr ? headA : nodeb->next;
}
return nodea;
}
};
很快,也很漂亮的解法!其思路在于:设链表A的长度为a,链表B的长度为b,在两条链表的相交点之前链表A的长度为c,链表B的长度为d,则有:
a - c = b - d -------> a + d = b + c
也就是说,有如下图的做法:
当两条链表存在相交的结点的时候,nodea和nodeb必然会走到相交的结点;当两条链表不相交时,nodea和nodeb都遍历了一遍链表a和链表b,最后变为nullptr。