题目:
编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:
在节点 c1 开始相交。
这一题之前听左神视频课讲过,
最暴力的方法就是用hash表,将A存入hash表,然后遍历B挨个检查,这样的时间复杂度为O(m+n);空间复杂度为O(m) or O(n)
然后就是利用双指针法,因为如果两个链表相交,说明后面一段链表长度肯定是相同的,那么只要去除长度差,从相同长度的节点开始遍历,那么每一次进行比较节点是否相同,最终要么找到相同的相交节点,要么都遍历到空为止;
因此时间复杂度为O(m+n);空间复杂度为O(1);
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(!headA||!headB) return NULL;
ListNode *nodeA=headA;
ListNode *nodeB=headB;
int sizeA=0;
int sizeB=0;
while(true)
{
if(nodeA->next) nodeA=nodeA->next;
else break;
++sizeA;
}
while(true)
{
if(nodeB->next) nodeB=nodeB->next;
else break;
++sizeB;
}
if(nodeA==nodeB){
if(sizeA>sizeB){
sizeA=sizeA-sizeB;
while(sizeA--)
{
headA=headA->next;
}
}
else{
sizeA=sizeB-sizeA;
while(sizeA--)
{
headB=headB->next;
}
}
while(true){
if(headA==headB) return headA;
headA=headA->next;
headB=headB->next;
}
}
else return NULL;
}
};
还有一种巧妙的解法是:将两个链表都拼接起来,在A的链表后面接上B;在B的链表后面接上A,这样大家长度一样,就直接从头节点开始遍历,然后,到最后末尾处,如果相交,后面肯定是一样的,否则返回NULL;
class Solution {
public:
ListNode* getIntersectionNode(ListNode* headA, ListNode* headB) {
ListNode *ha = headA, *hb = headB;
while (ha != hb) {
ha = ha != null ? ha->next : headB;
hb = hb != null ? hb->next : headA;
}
return ha;
}
}
时间复杂度为O(m+n);空间复杂度为O(1)