利用双指针求解:

1、先得到两个链表的长度;

2、如果两个链表的长度不同,则将长度较长的链表先移动,使得两个链表剩余的结点数相同;

3、两个链表再同时移动,如果两个链表有公共结点,移动过程中一定会相遇在第一个公共结点。

时间复杂度:o(n)

空间复杂度:o(1)

class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
	  	//特殊情况处理
        if (pHead1 == nullptr || pHead2 == nullptr)
            return nullptr;

        int length1 = 0;
        int length2 = 0;
        ListNode* ptemp1 = pHead1;
        ListNode* ptemp2 = pHead2;
        //得到两个链表的长度
        while (ptemp1) {
            length1++;
            ptemp1 = ptemp1->next;
        }
        while (ptemp2) {
            length2++;
            ptemp2 = ptemp2->next;
        }
        //长度较长的链表先移动,使得两个链表剩余的节点数相同
        if (length1 != length2) {
            if (length1 < length2) {
                for (int i = 0; i < length2 - length1; i++)
                    pHead2 = pHead2->next;             
            } else {
                for (int i = 0; i < length1 - length2; i++)
                    pHead1 = pHead1->next;          
            }
        } 
		while (pHead1 && pHead2) {
			if (pHead1 == pHead2)
                return pHead1;
            pHead1 = pHead1->next;
            pHead2 = pHead2->next;
        }

        return nullptr;
    }
};

如下有更便捷的写法

假设A、B两个链表的长度不同,但是,a+b = b+a 因此,可以让 a+b 作为链表A的新长度,b+a作为链表B的新长度。

当A链表移动到尾节点时,下一个节点变成B的头结点;当B链表移动到尾节点时,下一个节点变成A的头结点。

class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        ListNode *ta = pHead1, *tb = pHead2;
        while (ta != tb) {
            ta = ta ? ta->next : pHead2;
            tb = tb ? tb->next : pHead1;
        }
	  	//返回公共结点或者返回NULL
        return ta;
    }
};