Write a program to find the node at which the intersection of two singly linked lists begins.
For example, the following two linked lists:
A: a1 → a2 ↘ c1 → c2 → c3 ↗ B: b1 → b2 → b3begin to intersect at node c1
Notes:
- If the two linked lists have no intersection at all, return
null
. - The linked lists must retain their original structure after the function returns.
- You may assume there are no cycles anywhere in the entire linked structure.
- Your code should preferably run in O(n) time and use only O(1) memory.
找出两个链表的交点
如果没有交点则返回nullptr
方法一:原本想到是使用两个栈存储链表的数值,然后通过弹出元素进行比较。由于题目要求只能使用O(1)的space肯定不行。所以换了一个思路想到只要分别求出两个链表的长度然后比较最后相同的位数的链表元素即可。
/** * 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) return nullptr; int lenA = getListLength(headA), lenB = getListLength(headB); if (lenA > lenB) { for (int i = 0; i < lenA - lenB; i++) headA = headA->next; } else { for (int i = 0; i < lenB - lenA; i++) headB = headB->next; } while (headA != headB) { headA = headA->next; headB = headB->next; } return headA; } int getListLength(ListNode* head) { int len = 0; while (head) { len++; head = head->next; } return len; } }; // 59 ms
方法二:在discuss中看到有一个奇妙的解法。就是用环的思想来考虑这个问题,使用两个指针分别同步遍历两个链表,如果有链表遍历结束则开始转到另一个链表头部接着遍历,直到遍历到两个链表值相同,这个值就是两个链表的交点。
/** * 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) return nullptr; ListNode* nodeA = headA; ListNode* nodeB = headB; while (nodeA != nodeB) { nodeA = nodeA ? nodeA->next : headB; nodeB = nodeB ? nodeB->next : headA; } return nodeA; } }; // 43 ms