Enter two linked lists and find their first common node.

As shown in the following two linked lists:

The intersection begins at node c1.

Example 1:

Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3

Output: Reference of the node with value = 8

Input explanation: the value of intersection node is 8 (note that if two lists intersect, it cannot be 0). Starting from their respective headers, linked list A is [4,1,8,4,5], and linked list B is [5,0,1,8,4,5]. In A, there are 2 nodes before the intersection node; In B, there are 3 nodes before the intersection node.

Example 2:

Input: intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1

Output: Reference of the node with value = 2

Input explanation: the value of intersection node is 2 (note that if two lists intersect, it cannot be 0). Starting from the respective header, linked list A is [0,9,1,2,4], and linked list B is [3,2,4]. In A, there are 3 nodes before the intersection node; In B, there is 1 node before the intersection node.

Example 3:

Input: intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2

Output: null

Input explanation: starting from the respective header, linked list A is [2,6,4], and linked list B is [1,5]. Because the two linked lists do not intersect, intersectVal must be 0, and skipA and skipB can be any value.

Explanation: the two linked lists do not intersect, so null is returned.

be careful:

If two linked lists have no intersection, null is returned

After returning the results, the two linked lists must still maintain their original structure.

It can be assumed that there is no loop in the whole linked list structure.

The program shall meet the O(n) time complexity as much as possible, and only use O(1) memory.

## Method 1: hash set method

To determine whether two linked lists intersect, you can use a hash set to store linked list nodes.

Code language: cpp

/** * 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) { unordered_set<ListNode *> q; ListNode *tmp = headA; while(tmp!=nullptr){ //First, traverse the linked list headA, and add each node in the linked list headA to the hash set q.insert(tmp); tmp = tmp->next; } tmp = headB; while(tmp!=nullptr){ //Traverse the linked list headB. For each node traversed, judge whether the node is in the hash set if(q.count(tmp)){ //If the current node is in the hash set, the following nodes are in the hash set, that is, all nodes starting from the current node are the common nodes of the two linked lists return tmp; } tmp = tmp->next; } return nullptr; } };

forty-five / forty-five Pass test cases

Status: passed

Execution time: 52 ms

Memory consumption: 16.8 MB

Time complexity: O(m+n), where m And n Is the length of the linked list headA and headB respectively. You need to traverse the two linked lists once each.

Spatial complexity: O(m), where m is the length of the linked list headA. You need to use a hash set to store all nodes in the linked list headA.

Method 2: Double finger needling

Code language: cpp

/** * 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) { if(headA == nullptr || headB == nullptr){ //Only when the linked lists headA and headB are not empty can the two linked lists intersect return nullptr; } ListNode *pA = headA; ListNode *pB = headB; while(pA != pB){ //Each operation needs to update the pointers pA and pB at the same time (when the pointers pA and pB point to the same node or are empty, return the node they point to or null) pA = (pA == nullptr) ? headB : pA->next; //If the pointer pA is not empty, move the pointer pA to the next node; If the pointer pB is not empty, move the pointer pB to the next node pB = (pB == nullptr) ? headA : pB->next; //If the pointer pA is empty, move the pointer pA to the head node of the linked list headB; If the pointer pB is empty, move the pointer pB to the head node of the linked list headA } return pA; } };

forty-five / forty-five Pass test cases

Status: passed

Execution time: 40 ms

Memory consumption: 14.1 MB

Time complexity: O(m+n), where m And n Is the length of the linked list headA and headB respectively. Two pointers traverse two linked lists at the same time, and each pointer traverses two linked lists once each.

Space complexity: O(1).

Method 3: speed pointer

Code language: cpp

/** * 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) { //Get the length of the two linked lists int Alength = GetListLength(headA); int Blength = GetListLength(headB); int lenthDif = Alength - Blength; //Difference between the lengths of two linked lists ListNode *pheadlong = headA; ListNode *pheadshort = headB; if(lenthDif < 0){ lenthDif = Blength - Alength; pheadlong = headB; pheadshort = headA; } for(int i = 0; i < lenthDif; i++) //Let the long linked list go more (long short) distance first pheadlong = pheadlong->next; while(pheadshort != pheadlong){ //The long and short linked lists are traversed at the same time until the first public node is encountered if((pheadshort != nullptr)&&(pheadlong != nullptr)){ pheadlong = pheadlong->next; pheadshort = pheadshort->next; } else return nullptr; } return pheadshort; } unsigned int GetListLength(ListNode* pHead){ //Get linked list length function unsigned int nlength = 0; ListNode* pNode = pHead; while(pNode != nullptr){ ++nlength; pNode = pNode->next; } return nlength; } };

forty-five / forty-five Pass test cases

Status: passed

Execution time: 36 ms

Memory consumption: 14.1 MB