Leetcode-160: Intersection of Two Linked Lists (两链表相交求交点, 经典题)

解法1: 最简单的方法。两链表同时开始遍历,算长度。然后长的那个截去多余长度再重新开始遍历,如果遍历过程中有两节点一样则返回该节点,否则返回NULL。

ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    if (!headA || !headB) return NULL;

    int countA=0;
    int countB=0;
    ListNode* nodeA=headA;
    ListNode* nodeB=headB;

    while(nodeA) {
        countA++;
        nodeA=nodeA->next;
    }

    while(nodeB) {
        countB++;
        nodeB=nodeB->next;
    }

    ListNode* shortListHead = (countA<countB)? headA : headB;
    ListNode* longListHead = (countA>=countB)? headA : headB;

    for (int i=0; i<abs(countA-countB); ++i)
        longListHead=longListHead->next;

    while(shortListHead) { //now shortList and longList have the same length
        if (shortListHead==longListHead) return shortListHead;
        else {
            shortListHead=shortListHead->next;
            longListHead=longListHead->next;
        }
    }

    return NULL;
}

解法2: 其中一链表变环,然后就跟求链表环首地址一样了。要用快慢指针。下次补充。

解法3:两链表同时遍历,短的那个变环。假设短链表长度为a, 长链表长度为b, 如果他们尾部有交集,则短的那个到最后时,长的那个还有b-a才到最后。这时,我们把短链表首尾相连,然后p1指向长链表遍历所在的当前位置(的下一个位置), p2指向长链表的头部,同时开始遍历,则p1再走b-a+a=b步就到了相交处,p2走b步也到了相交处,此时p1和p2重合。如果p2走完了也没有发现和p1重合,则返回NULL。
代码如下:

ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    if (!headA || !headB) return NULL;

    ListNode* p1=headA;
    ListNode* p2=headB;
    ListNode* pEndA;
    ListNode* pEndB;

    while(p1 && p2) {
        if (p1==p2) return p1;
        if (p1->next && p2->next) {  //Note the [1] and [1] case
            p1=p1->next;
            p2=p2->next;
        }else break;
    }

    if (p1->next==NULL) {
        if (!p2 || !p2->next) return NULL;
        pEndA=p1;
        p1->next=headA;
        p1=p2->next;
        p2=headB;
        while(p1 && p2 && p1!=p2) {
            p1=p1->next;
            p2=p2->next;
        }
        pEndA->next=NULL; //remove the cycle to resume the link list
        if (p1==p2) return p1;
        else return NULL;
    } else if (p2->next==NULL) {
        if (!p1 || !p1->next) return NULL;
        pEndB=p2;
        p2->next=headB;
        p2=p1->next;
        p1=headA;
        while(p1 && p2 && p1!=p2) {
            p1=p1->next;
            p2=p2->next;
        }
        pEndB->next=NULL;  //remove the cycle to resume the link list
        if (p1==p2) return p2;
        else return NULL;
    }

    return NULL;
}

注意:
1)变环了最后要断开,不能破坏链表结构。
2)注意各种相交,重合,和不重合的case。

此题测试例子较多。代码如下:

int main()
{
    cout<<"test case 1"<<endl;
    ListNode a0_1(3);
    ListNode a0_2(4);
    ListNode b0_1(9);
    ListNode b0_2(12);
    ListNode b0_3(72);
    ListNode c0_1(8);
    ListNode c0_2(45);
    ListNode c0_3(29);
    a0_1.next=&a0_2;
    a0_2.next=&c0_1;
    c0_1.next=&c0_2;
    c0_2.next=&c0_3;
    b0_1.next=&b0_2;
    b0_2.next=&b0_3;
    b0_3.next=&c0_1;
    ListNode *t=getIntersectionNode(&a0_1, &b0_1);
    if (t) cout<<t->val<<endl;

    cout<<"test case 2"<<endl;
    ListNode a1_1(1);
    ListNode a1_2(3);
    ListNode a1_3(5);
    ListNode a1_4(7);
    ListNode a1_5(9);
    ListNode a1_6(11);
    ListNode a1_7(13);
    ListNode a1_8(15);
    ListNode a1_9(17);
    ListNode a1_10(19);
    ListNode a1_11(21);
    ListNode b1_1(2);

    a1_1.next=&a1_2;
    a1_2.next=&a1_3;
    a1_3.next=&a1_4;
    a1_4.next=&a1_5;
    a1_5.next=&a1_6;
    a1_6.next=&a1_7;
    a1_7.next=&a1_8;
    a1_8.next=&a1_9;
    a1_9.next=&a1_10;
    a1_10.next=&a1_11;

    t=getIntersectionNode(&a1_1, &b1_1);
    if (t) cout<<t->val<<endl;

    cout<<"test case 3"<<endl;
    ListNode a2_1(1);
    ListNode a2_2(2);
    ListNode a2_3(3);
    ListNode a2_4(4);
    ListNode a2_5(5);
    ListNode a2_6(6);
    ListNode a2_7(7);
    ListNode a2_8(8);
    ListNode a2_9(9);
    ListNode a2_10(10);
    ListNode a2_11(11);
    ListNode a2_12(12);
    ListNode a2_13(13);

    a2_1.next=&a2_2;
    a2_2.next=&a2_3;ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    if (!headA || !headB) return NULL;

    ListNode* p1=headA;
    ListNode* p2=headB;
    ListNode* pEndA;
    ListNode* pEndB;

    while(p1 && p2) {
        if (p1==p2) return p1;
        if (p1->next && p2->next) {  //Note the [1] and [1] case
            p1=p1->next;
            p2=p2->next;
        }else break;
    }

    if (p1->next==NULL) {
        if (!p2 || !p2->next) return NULL;
        pEndA=p1;
        p1->next=headA;
        p1=p2->next;
        p2=headB;
        while(p1 && p2 && p1!=p2) {
            p1=p1->next;
            p2=p2->next;
        }
        pEndA->next=NULL; //remove the cycle to resume the link list
        if (p1==p2) return p1;
        else return NULL;
    } else if (p2->next==NULL) {
        if (!p1 || !p1->next) return NULL;
        pEndB=p2;
        p2->next=headB;
        p2=p1->next;
        p1=headA;
        while(p1 && p2 && p1!=p2) {
            p1=p1->next;
            p2=p2->next;
        }
        pEndB->next=NULL;  //remove the cycle to resume the link list
        if (p1==p2) return p2;
        else return NULL;
    }

    return NULL; //???
}
    a2_3.next=&a2_4;
    a2_4.next=&a2_5;
    a2_5.next=&a2_6;
    a2_6.next=&a2_7;
    a2_7.next=&a2_8;
    a2_8.next=&a2_9;
    a2_9.next=&a2_10;
    a2_10.next=&a2_11;
    a2_11.next=&a2_12;
    a2_12.next=&a2_13;

    ListNode *pb1=&a2_1;
    ListNode *pb2=&a2_2;
    ListNode *pb3=&a2_3;
    ListNode *pb4=&a2_4;
    ListNode *pb5=&a2_5;
    ListNode *pb6=&a2_6;
    ListNode *pb7=&a2_7;
    ListNode *pb8=&a2_8;
    ListNode *pb9=&a2_9;
    ListNode *pb10=&a2_10;
    ListNode *pb11=&a2_11;
    ListNode *pb12=&a2_12;
    ListNode *pb13=&a2_13;

    t=getIntersectionNode(&a2_1, pb1);
    if (t) cout<<t->val<<endl;

    cout<<"test case 4"<<endl;
    ListNode a3_1(3);
    ListNode a3_2(4);
    ListNode a3_3(5);
    ListNode a3_4(6);
    ListNode a3_5(7);
    ListNode a3_6(8);
    ListNode a3_7(9);
    ListNode a3_8(10);
    ListNode a3_9(11);
    ListNode a3_10(12);
    ListNode a3_11(13);
    ListNode a3_12(14);
    ListNode a3_13(15);

    a3_1.next=&a3_2;
    a3_2.next=&a3_3;
    a3_3.next=&a3_4;
    a3_4.next=&a3_5;
    a3_5.next=&a3_6;
    a3_6.next=&a3_7;
    a3_7.next=&a3_8;
    a3_8.next=&a3_9;
    a3_9.next=&a3_10;
    a3_10.next=&a3_11;
    a3_11.next=&a3_12;
    a3_12.next=&a3_13;

    ListNode b3_1(2);
    ListNode *pb3_2=&a3_1;
    ListNode *pb3_3=&a3_2;
    ListNode *pb3_4=&a3_3;
    ListNode *pb3_5=&a3_4;
    ListNode *pb3_6=&a3_5;
    ListNode *pb3_7=&a3_6;
    ListNode *pb3_8=&a3_7;
    ListNode *pb3_9=&a3_8;
    ListNode *pb3_10=&a3_9;
    ListNode *pb3_11=&a3_10;
    ListNode *pb3_12=&a3_11;
    ListNode *pb3_13=&a3_12;
    ListNode *pb3_14=&a3_13;
    b3_1.next=pb3_2;

    t=getIntersectionNode(&a3_1, &b3_1);
    if (t) cout<<t->val<<endl;

    cout<<"test case 5"<<endl;
    ListNode a5_1(1);
    ListNode a5_2(3);
    ListNode a5_3(5);
    ListNode a5_4(7);
    ListNode a5_5(9);
    ListNode a5_6(10);
    ListNode a5_7(11);
    ListNode a5_8(12);
    ListNode a5_9(13);
    ListNode a5_10(14);
    ListNode a5_11(15);
    ListNode a5_12(16);
    ListNode a5_13(17);
    ListNode a5_14(18);
    ListNode a5_15(19);
    ListNode a5_16(20);
    ListNode a5_17(21);
    ListNode a5_18(22);
    ListNode a5_19(23);
    ListNode a5_20(24);
    ListNode a5_21(25);
    ListNode a5_22(26);

    a5_1.next=&a5_2;
    a5_2.next=&a5_3;
    a5_3.next=&a5_4;
    a5_4.next=&a5_5;
    a5_5.next=&a5_6;
    a5_6.next=&a5_7;
    a5_7.next=&a5_8;
    a5_8.next=&a5_9;
    a5_9.next=&a5_10;
    a5_10.next=&a5_11;
    a5_11.next=&a5_12;
    a5_12.next=&a5_13;
    a5_13.next=&a5_14;
    a5_14.next=&a5_15;
    a5_15.next=&a5_16;
    a5_16.next=&a5_17;
    a5_17.next=&a5_18;
    a5_18.next=&a5_19;
    a5_19.next=&a5_20;
    a5_20.next=&a5_21;
    a5_21.next=&a5_22;

    ListNode *pb5_1=&a5_6;
    ListNode *pb5_2=&a5_7;
    ListNode *pb5_3=&a5_8;
    ListNode *pb5_4=&a5_9;
    ListNode *pb5_5=&a5_10;
    ListNode *pb5_6=&a5_11;
    ListNode *pb5_7=&a5_12;
    ListNode *pb5_8=&a5_13;
    ListNode *pb5_9=&a5_14;
    ListNode *pb5_10=&a5_15;
    ListNode *pb5_11=&a5_16;
    ListNode *pb5_12=&a5_17;
    ListNode *pb5_13=&a5_18;
    ListNode *pb5_14=&a5_19;
    ListNode *pb5_15=&a5_20;
    ListNode *pb5_16=&a5_21;
    ListNode *pb5_17=&a5_22;

    t=getIntersectionNode(&a5_1, pb5_1);
    if (t) cout<<t->val<<endl;

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值