leetcode160:相交链表

题目:

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

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

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

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

思路:

简单来说,就是求两个链表交点节点的指针

要注意:不是数值相等,而是指针相等

代码实现:

方法一:长度差

①先分别计算两个链表的长度,将curA指向长的链表,curB指向短的链表

②再将两个链表长度相减,得到差值

③让curA先走差值大小的长度,再同时移动两个指针

④最后返回相交的节点

cpp 复制代码
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* curA = headA;
        ListNode* curB = headB;
        int lenA = 0, lenB = 0;
        while (curA != NULL) { // 求链表A的长度
            lenA++;
            curA = curA->next;
        }
        while (curB != NULL) { // 求链表B的长度
            lenB++;
            curB = curB->next;
        }
        curA = headA;
        curB = headB;
        // 让curA为最长链表的头,lenA为其长度
        if (lenB > lenA) {
            swap (lenA, lenB);
            swap (curA, curB);
        }
        // 求长度差
        int gap = lenA - lenB;
        // 让curA和curB在同一起点上(末尾位置对齐)
        while (gap--) {
            curA = curA->next;
        }
        // 遍历curA 和 curB,遇到相同则直接返回
        while (curA != NULL) {
            if (curA == curB) {
                return curA;
            }
            curA = curA->next;
            curB = curB->next;
        }
        return NULL;
    }
};

但是这种方法要遍历链表两次,一次得到长度,一次寻找节点,我们可以使用哈希表来存储遍历过的节点,如果当前节点已经在哈希表中存在,就直接返回

方法2:哈希表

①先遍历一遍其中一个链表,将里面的节点存入哈希表中

②再遍历另一个链表,判断链表中的节点是否存在哈希表中

③如果存在就说明相交,全部遍历完还没找到相交节点说明不相交

cpp 复制代码
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if (!headA || !headB) return nullptr;        
        unordered_set<ListNode*> visited;
        ListNode* curr = headA;
        // 第一遍遍历链表A,将所有节点加入哈希表
        while (curr) {
            visited.insert(curr);
            curr = curr->next;
        }
        // 第二遍遍历链表B,检查节点是否已在哈希表中
        curr = headB;
        while (curr) {
            if (visited.find(curr) != visited.end()) {
                return curr;  // 找到第一个公共节点
            }
            curr = curr->next;
        }        
        return nullptr;  // 没有交点
    }
};

哈希表的方法比较清晰简单,但是需要使用到额外的空间,可以使用双指针的方式,避免额外空间的使用

方法3.双指针

①将两个指针分别指向两个链表的头节点

②当两个指针不相同时,分别移动两个指针

③当其中一个指针指向当前链表结尾时,将其移动到另一个链表的头节点,继续遍历

④若相交,两个指针一定会在相交节点相遇,若不相交,两个指针一定会同时指向最后的NULL节点

cpp 复制代码
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if(headA==nullptr||headB==nullptr)return nullptr;
        ListNode* h1 = headA;
        ListNode* h2 = headB;
        while(h1!=h2){
            //如果遍历完当前链表,就将其移动到另一个链表的头节点
            if(h1==nullptr){
                h1 = headB;
            }else{
                h1 = h1->next;
            }
            if(h2==nullptr){
                h2 = headA;
            }else{
                h2=h2->next;
            }
        }
        return h1;
    }
};

双指针的方法没有使用到额外的空间,并且时间复杂度是O(n+m),属于是较优的解法了

这题我们从最开始的两次遍历,到使用额外空间的一次遍历,再到不使用额外空间的一次遍历,多次优化代码,说明一道题不只有一种解法,可以进行不断的优化,找到最优解

相关推荐
广州灵眸科技有限公司1 天前
瑞芯微(EASY EAI)RV1126B 音频电路
开发语言·人工智能·深度学习·算法·yolo·音视频
Dlrb12111 天前
数据结构-链表
数据结构·链表·逻辑结构·单向链表·物理结构·valgrind工具
小的~~1 天前
算法题:只出现一次的数字
数据结构·算法
灵智实验室1 天前
PX4状态估计技术EKF2详解(六):EKF2 磁力计融合——从航向修正到 3D 姿态约束
算法·无人机·px 4
JieE2121 天前
手把手带你用虚拟头节点实现单链表,搞定所有边界问题
javascript·算法
一切皆是因缘际会1 天前
从概率拟合到内生心智:七层投影架构重构AGI数字生命新范式
大数据·数据结构·人工智能·重构·架构·agi
历程里程碑1 天前
56 . 高效ET非阻塞IO服务器设计指南
java·运维·服务器·开发语言·数据结构·c++·排序算法
搞科研的小刘选手1 天前
【大连市计算机学会主办】第三届图像处理、智能控制与计算机工程国际学术会议(IPICE 2026)
图像处理·人工智能·深度学习·算法·计算机·数据挖掘·智能控制
南境十里·墨染春水1 天前
数据结构 —— 顺序表
数据结构
人月神话-Lee1 天前
【图像处理】高斯模糊——最优雅的模糊算法
图像处理·人工智能·算法·ios·ai编程·swift