LeetCode[Linked List]: Intersection of Two Linked Lists

来源:互联网 发布:异步网络框架 编辑:程序博客网 时间:2024/06/05 15:03

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
原创粉丝点击