LeetCode[Linked List]: Intersection of Two Linked Lists

Write a program to find the node at which the intersection of two singly linked lists begins.
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.

这个题目没有能自己独立得到解法,在Discuss上得到一种解法:

  1. 获取两条链表的长度;
  2. 让两指针分别对齐到距离尾节点相同距离的节点;
  3. 一步一步往后移直到找到交汇点。

根据以上思路,我做了以下C++实现:

ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    int lenA = 0, lenB = 0;
    for (ListNode *curA = headA; curA != nullptr; curA = curA->next) ++lenA;
    for (ListNode *curB = headB; curB != nullptr; curB = curB->next) ++lenB;

    ListNode *curA = headA, *curB = headB;
    while (lenA > lenB) {
        curA = curA->next;
        --lenA;
    }
    while (lenB > lenA) {
        curB = curB->next;
        --lenB;
    }

    while (curA != curB) {
        curA = curA->next;
        curB = curB->next;
    }

    return curA;
}


然后我在Solution上看到一种更独特的解法:

  1. 指针pA、pB分别指向链表A、B的头结点,每次后移一个节点;
  2. 当pA到达A的尾节点,将pA重置为B的头节点;同样,当pB到达B的尾节点,将pB重置为A的头结点;
  3. 两指针继续后移,如果两者相遇,那么相遇点即是两链表的交汇点。

至于为什么上述方法可以生效,我想可以这么理解:不失一般性地,可以假设A链表短于B链表,那么pA先指向A得尾节点,被重置为B的头结点,那么当pB被重置时,走过的总步数为B链表的长度,那么此时两指针分别距离两链表的尾节点的距离是一样的,所以在往后移的过程中,如果两链表存在交汇点,那么两指针必然同时到达交汇点,如果不存在,那么两指针也是同时到达尾节点。

根据以上思路,我做了如下C++实现:

ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    ListNode *pA = headA, *pB = headB;
    int flag = 2;
    while (flag) {
        if (!pA) {
            pA = headB;
            --flag;
        }
        else pA = pA->next;

        if (!pB) {
            pB = headA;
            --flag;
        }
        else pB = pB->next;
    }

    while (pA != pB) {
        pA = pA->next;
        pB = pB->next;
    }

    return pA;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值