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 → b3
begin 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.
/**
* 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) {
ListNode* tempA;
ListNode* tempB;
while(headA)
{
tempA=headA;
tempB=headB;
while(tempB)
{
if(tempA==tempB)return tempA;
tempB=tempB->next;
}
headA=headA->next;
}
return NULL;
}
};
/**
* 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*> s;
while(headA)
{
s.insert(headA);
headA=headA->next;
}
while(headB)
{
if(s.find(headB)!=s.end())return headB;
headB=headB->next;
}
return NULL;
}
};
哈哈哈過了,用時也還算低,但是直覺告訴我這不是出題人的本意,肯定還有更巧妙的做法。果不其然,圍觀了一下大佬的做法,簡直變身小迷弟給大佬瘋狂打call。這是大佬的代碼:/**
* 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||!headB) return NULL;
ListNode *a=headA,*b=headB;
while(a!=b)
{
a=a?a->next:headB;
b=b?b->next:headA;
}
return a;
}
};
兩個字:優美- 假設A長度m,B長度n,兩個指針都會在m+n次循環後同時抵達空指針,使得a!=b不成立退出循環,防止了死循環的出現,返回NULL。
- 假設倒數第k個點是交集,由於交點之後的點是共用的,所以兩個指針都會在m+n-k次循環後抵達相同節點,使得a!=b不成立退出循環,返回交點指針。