题目:160. 相交链表
思路:两个链表相交,就意味着有一段空间是共有的。这就是为什么“只需要找到首个相交节点,而不用确保后续节点也相等”的理由。
方法一:哈希表。用哈希表sta存储链表headA的所有节点,接着遍历链表headB。如果哈希表中存在该节点,那该点就是首个相交节点。时间复杂度0(m+n),空间复杂度0(m)。
/**
* 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 *> sta;
while(headA){
sta.insert(headA);
headA=headA->next;
}
ListNode * tmp=nullptr;
while(headB){
if(sta.count(headB)){
tmp=headB;
break;
}
headB=headB->next;
}
return tmp;
}
};
方法二:双指针。原理就是让指针pA遍历链表headA+headB,指针pB遍历链表headB+headA。指针pA、pB同时移动,如果存在相等的情况,直接退出返回当前值即可。
原理:如果有相交的部分,且长度为c。链表headA的长度为m=a+c,链表headB的长度为n=b+c。
1.当a == b时,直接就可以遇到相等。
2.当a!=b时,通过链表接续,a+c+b == b+c+a,也可以遇到。
如果没有相交的部分,即使接续后,走了a+c+b+c == b+c+a+c步后,最后还是会指向nullptr,然后相等退出。
时间复杂度0(m+n),空间复杂度0(1)。
/**
* 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 * pA=headA,*pB=headB;
//直到相等才退出
while(pA!=pB){
//到尾部了,就续集链表headB
if(pA==nullptr) pA=headB;
else pA=pA->next;
//到尾部了,就续集链表headA
if(pB==nullptr) pB=headA;
else pB=pB->next;
}
return pA;
}
};