题目描述:
编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:
在节点 c1 开始相交。
示例 1:
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 输出:Reference of the node with value = 8 输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
有三种方法:
一:直接遍历,
时间复杂度 O(mn)
空间复杂度 O(1)
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* p=headA;
while(p)
{
ListNode* q=headB;
while(q)
{
if(p==q)
return q;
q=q->next;
}
p=p->next;
}
return NULL;
}
};
第二种方法:
时间复杂度O(max(m,n))
空间复杂度O(1)
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int lena =0,lenb= 0;
ListNode *p =headA,*q =headB;
while(p){ lena++;p=p->next;}
while(q){ lenb++;q=q->next;}
p= (lena>lenb)? headA:headB; //让p指向长的,q指向短的
q= (lena>lenb)? headB:headA;
if(lena<lenb) swap(lena,lenb);
while(lena--!=lenb) {p=p->next;}
//使p向后移即为,使得p和q在相交前的同一个起始点开始同时同步向后遍历
while(p&&q){
if(p==q) return p;
p=p->next;
q=q->next;
}
return NULL;
}
};
第三种方法:
时间复杂度:O(M+N)
空间复杂度: O(1)
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (headA==NULL ||headB==NULL)
return NULL;
ListNode *p=headA,*q=headB;
//第一轮分别到达表尾后就指向另一链表的表头,第二轮因为两个指针两轮都共走了m+n次,所以第二轮如果没有遇到相交的,两者最后就会同时等于null
while(p!=q)
{
p=(p==NULL?headB:p->next);
q=(q==NULL?headA:q->next);
}
return q;
}
};