leetcode——面试题02.07——链表相交

本文探讨如何利用unordered_set实现链表相交的判定,重点在于理解节点引用的重要性,并提供了一个考虑链表长度和交点位置的优化算法。通过实例代码解释了如何找到两个单向链表的交点,即使它们的值不同,但引用指向相同的节点。

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

题目:
给定两个(单向)链表,判定它们是否相交并返回交点。请注意相交的定义基于节点的引用,而不是基于节点的值。换句话说,如果一个链表的第k个节点与另一个链表的第j个节点是同一节点(引用完全相同),则这两个链表相交。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) 
    {
        unordered_set<ListNode*> hash;
        ListNode* node1 = headA, * node2 = headB;
        while(node1 != nullptr)
        {
            hash.insert(node1);
            node1 = node1->next;
        }
        while(node2 != nullptr)
        {
            if(hash.count(node2) > 0)   return node2;
            node2 = node2->next;
        }
        return nullptr;
    }
};
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
/*
题解:题目要求是求出两个链表交点的指针,这里的交点不是指数值相等,而是指针相等
    刚开始想错了,这里是节点,可不是直线,不能与直线相交混淆了啊!!!
    从某个节点开始一旦相交,那么后面的都是是相等的,这里的相交其实是可以理解为  重合 ,地址相等 + 值相等
    正是因为如此,如果两个链表相交的话,尾部一定是相等的!即从中间某处开始 到尾部 是完全相等(重合)!!!
*/

public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) 
    {
        if(headA == nullptr || headB == nullptr)    return nullptr;
        ListNode* tempA = headA;
        ListNode* tempB = headB;
        int lenA = 0;
        int lenB = 0;
        // 一定得先分清楚 两个链表谁比较长,所以需要先求长度
        while(tempA != nullptr)
        {
            lenA++;
            tempA = tempA->next;
        }
        while(tempB != nullptr)
        {
            lenB++;
            tempB = tempB->next;
        }
        // 1::两个while完成后,临时节点为位置已经都变成空节点了,所以这里要重新赋值一下
        tempA = headA;
        tempB = headB;

        // 2::将A定为比较大的那个,如果B大,则交换,注意这里的交换,可以直接用 swap函数。我都不知道
        if(lenB > lenA)
        {
            swap(tempA, tempB);
            swap(lenA, lenB);
        }
        int count = lenA - lenB;

        while(count)
        {
            tempA = tempA->next;
            count--;
        }
        // 上面这个while循环可以替换为 : while(count--)  tempA = tempA->next;


        // 这里这个 while 循环可以改一下,将判断条件设置为 tempA != nullptr,这样就不用多做一次减法
        while(lenB)
        {
            if(tempA == tempB)
            {
                return tempA;
            }
            tempA = tempA->next;
            tempB = tempB->next;
            lenB--;
        }
        return nullptr;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值