LeetCode 160. Intersection of Two Linked Lists

本文介绍了一种高效算法,用于查找两个单链表的首个交叉节点。该算法能在O(n)时间内完成,并仅使用O(1)额外空间,适用于无环链表结构。

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

For example, the following two linked lists:

A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3

begin to intersect at node c1.

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.

题意:找出两个单链表的交叉点,样例返回节点c1。
注意:
- 如果没有交叉点返回NULL。
- 函数返回时必须恢复链表原来的结构。
- 假设整个链表结构没有形成圈的地方。
- 时间复杂度O(n),空间复杂度O(1)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    /*
        看了讨论,发现很聪明的办法:同时遍历A、B,当任意遍历A、B的指针为空后,指向B、A重新开始遍历
        (1) 如果有交叉点,则有一刻会指向交叉点
        (2) 如果没有交叉点,则有一刻会同时指空
    1.        a1 -> a2
                     ↘  
                      c1 -> c2 -> c3
                     ↗ 
        b1 -> b2 -> b3
        p1遍历次序 :a1 -> a2 -> NU -> c1 -> c2 -> c3 -> NU -> b1 -> b2 -> b3 -> c1
        p2遍历次序 :b1 -> b2 -> b3 -> NU -> c1 -> c2 -> c3 -> NU -> a1 -> a2 -> c1

    2.  a1 -> a2 -> a3
        b1 -> b2 -> b3
        p1遍历次序 :a1 -> a2 -> a3 -> NULL
        p2遍历次序 :b1 -> b2 -> b3 -> NULL


    3.  a1 -> a2 -> a3
        b1 -> b2 -> b3 -> b4
        p1遍历次序 :a1 -> a2 -> a3 -> NU -> b1 -> b2 -> b3 -> b4 -> NULL
        p2遍历次序 :b1 -> b2 -> b3 -> b4 -> NU -> a1 -> a2 -> a3 -> NULL

    4.  a1(b1) -> a2(b2) 就是同一条链表

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

        ListNode* p1 = headA, *p2 = headB;
        while(p1 != NULL && p2 != NULL && p1 != p2){
            p1 = p1 -> next;
            p2 = p2 -> next;
            if(p1 == p2) return p1;     // 相遇
            if(p1 == NULL) p1 = headB;
            if(p2 == NULL) p2 = headA;
        }
        // headA == headB
        return p1;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值