LeetCode热题100——160.相交链表(两种解法)

题目:

给你两个单链表的头节点 headAheadB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null

图示两个链表在节点 c1 开始相交**:**

题目数据 保证 整个链式结构中不存在环。

注意 ,函数返回结果后,链表必须 保持其原始结构

方法一:哈希集合

思路

链表相交的定义是:两个链表从某个节点开始,后续的所有节点在内存中完全相同(即地址相同)。因此,我们可以利用哈希集合存储其中一个链表的所有节点地址,然后遍历另一个链表,第一个存在于集合中的节点就是相交的起始节点。

算法步骤:

1.创建一个哈希集合 unordered_set<ListNode*>,用于存储节点地址。

2.遍历链表 headA,将每个节点的地址插入集合。

3.遍历链表 headB,对于每个节点,检查其地址是否已经在集合中:

  • 如果存在,说明该节点同时属于两个链表,即相交的起始节点,直接返回。
  • 如果不存在,继续遍历下一个节点。

4.若遍历完链表 headB 仍未找到,则两个链表不相交,返回 NULL。

答案:

cpp 复制代码
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        unordered_set<ListNode *> visited;//存储节点地址
        //遍历链表 headA,将每个节点的地址插入集合
        ListNode *temp=headA;
        while(temp!=NULL){
            visited.insert(temp);
            temp=temp->next;
        }
        //遍历链表 headB,对于每个节点,检查其地址是否已经在集合中
        temp=headB;
        while(temp!=NULL){
            if(visited.count(temp)){
                return temp;//如果存在,返回节点
            }
            temp=temp->next;
        }
        return NULL;//如果链表不相交,返回NULL
    }
};

要点:

  • 必须使用节点地址(指针值)进行比较,而不是节点值。因为值相同并不代表节点相同。

方法二:双指针(神仙解法)

思路:

两个链表如果相交,它们从相交节点开始到末尾的节点是完全相同的。设:

  • 链表 headA 的不相交部分长度为 a,相交部分长度为 c。
  • 链表 headB 的不相交部分长度为 b,相交部分长度为 c。

若两个指针分别从两个链表头指针开始同步前进,当指针走到自己链表的末尾时,转向另一个链表的头部继续走,直到走到相交点。那么:

  • 指针 pA 走过的路程:a + c + b(先走完A,再走完B的不相交部分到达交点)
  • 指针 pB 走过的路程:b + c + a(先走完B,再走完A的不相交部分到达交点)

两者路程相等 ,因此它们一定会在相交节点相遇。如果两个链表不相交,它们最终会同时走到 NULL。

算法步骤:

1.若任一链表为空,直接返回 NULL。

2.初始化两个指针 pa = headA,pb = headB。

3.循环,当 pa != pb 时:

  • 如果 pa 为空,则指向 headB;否则指向 pa->next。
  • 如果 pb 为空,则指向 headA;否则指向 pb->next。

4.循环结束后,pa(或 pb)即为相交节点,返回。

答案:

cpp 复制代码
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if(headA==NULL||headB==NULL) return NULL;
        ListNode *pa=headA;
        ListNode *pb=headB;        
        while(pa!=pb){
            pa=pa==NULL?headB:pa->next;
            pb=pb==NULL?headA:pb->next; 
        }
        return pa;
    }
};
相关推荐
Tisfy18 小时前
LeetCode 3345.最小可整除数位乘积 I:暴力枚举(从n开始尝试)
数学·算法·leetcode·题解·枚举
DolphinDB智臾科技18 小时前
告别 TB 级数据搬运:DolphinDB 滤波算法库,重塑物联网数据价值链
物联网·算法
可编程芯片开发19 小时前
基于双PI控制器结构的六步逆变器供电无刷直流电机调速simulink仿真
算法
Sagittarius_A*19 小时前
后量子密码|通识认知 02|量子威胁核心原理:Shor 算法如何击穿传统公钥密码
算法·信息安全·密码学·量子计算
青山木19 小时前
Hot 100 --- 在排序数组中查找元素的第一个和最后一个位置
java·数据结构·算法·leetcode
其美杰布-富贵-李20 小时前
聚类算法详解:K-means、层次聚类与 DBSCAN
算法·机器学习·kmeans·聚类
碧海银沙音频科技研究院20 小时前
4 BES2710编译环境搭建方法
嵌入式硬件·算法
mifengxing20 小时前
LeetCode 238 除自身以外数组的乘积|无除法O(n)时间+O(1)空间双解法
java·算法·leetcode
依然鸣21 小时前
PTA团体程序设计天梯赛L2真题讲解L2-045-048
数据结构·c++·经验分享·学习·算法·pat考试·pat
丢掉幻想准备斗争21 小时前
5.5树与二叉树的应用
算法