LintCode 380: Intersection of Two Linked Lists

本文介绍两种寻找两个链表交汇节点的方法。方法一采用双指针技术,在遍历完各自链表后交换头部继续遍历,直到相遇。方法二首先测量两链表长度,通过让较长链表先走长度差步数再同步前进的方式找到交点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

380 · Intersection of Two Linked Lists
Algorithms
Medium
Accepted Rate
46%
Description
Solution
Notes
Discuss
Leaderboard
Record

Description
Write a program to find the node at which the intersection of two singly linked lists begins.

Wechat reply 【Google】 get the latest requent Interview questions. (wechat id : jiuzhang0607)

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.
Example
Example 1:

Input:
A: a1 → a2

c1 → c2 → c3

B: b1 → b2 → b3
Output: c1
Explanation :begin to intersect at node c1.
Example 2:

Input:
Intersected at 6
1->2->3->4->5->6->7->8->9->10->11->12->13->null
6->7->8->9->10->11->12->13->null
Output: Intersected at 6
Explanation:begin to intersect at node 6.
Challenge
Your code should preferably run in O(n) time and use only O(1) memory.

解法1:
链表A走完后从链表B头开始走,链表B走完后从链表A头开始走,
假设链表A和链表B公用部分长度为c,相遇前A长度为a,B长度为b,则两个指针都走完a+b+c后会在汇合点相遇。

/**
 * Definition of singly-linked-list:
 * class ListNode {
 * public:
 *     int val;
 *     ListNode *next;
 *     ListNode(int val) {
 *        this->val = val;
 *        this->next = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param headA: the first list
     * @param headB: the second list
     * @return: a ListNode
     */
    ListNode * getIntersectionNode(ListNode * headA, ListNode * headB) {
        if (!headA || !headB) return NULL;
        ListNode *pA = headA;
        ListNode *pB = headB;
        while(pA && pB) {
            if (pA == pB) return pA; 
            pA = pA->next;
            pB = pB->next;
            if (!pA) pA = headB;
            if (!pB) pB = headA;
        }
        return NULL;
    }
};

可以简化为:

class Solution {
public:
    /**
     * @param headA: the first list
     * @param headB: the second list
     * @return: a ListNode
     */
    ListNode * getIntersectionNode(ListNode * headA, ListNode * headB) {
        // write your code here
        if (headA == nullptr || headB == nullptr) {
            return nullptr;
        }
        ListNode *pA = headA, *pB = headB;
        while (pA != pB) {
            pA = (pA == nullptr) ? headB : pA->next;
            pB = (pB == nullptr) ? headA : pB->next;
        }
        return pA;
    }
};

这个简化的代码更好。因为如果链表A和B不相遇的话,那么pA和pB都走完了A链表+B链表的长度后会都变成nullptr,此时会返回nullptr。

解法2:经典的解法。先测出两个链表的长度,长度差为gap,然后长链表从头开始走gap步,此时两个链表开始同步走,直至相遇。若不相遇,走到终点返回nullptr。

/**
 * Definition of singly-linked-list:
 * class ListNode {
 * public:
 *     int val;
 *     ListNode *next;
 *     ListNode(int val) {
 *        this->val = val;
 *        this->next = NULL;
 *     }
 * }
 */
class Solution {
public:
    /**
     * @param headA: the first list
     * @param headB: the second list
     * @return: a ListNode
     */
    ListNode * getIntersectionNode(ListNode * headA, ListNode * headB) {
        // write your code here
        if (headA == nullptr || headB == nullptr) {
            return nullptr;
        }
        int lenA = 0, lenB = 0;
        ListNode *pA = headA, *pB = headB;
        while(pA) {
            lenA++;
            pA = pA->next;
        }
        while(pB) {
            lenB++;
            pB = pB->next;
        }
        ListNode *pLong = lenA >= lenB ? headA : headB;
        ListNode *pShort = lenA >= lenB ? headB : headA;
        int lenLong = max(lenA, lenB);
        int lenShort = min(lenA, lenB);
        int gap = lenLong - lenShort;
        for (int i = 0; i < gap; i++) pLong = pLong->next;
        while (pLong != pShort) {
            pLong = pLong->next;
            pShort = pShort->next;
        }
        return pLong;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值