leetcode160:相交链表

题目:

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 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),属于是较优的解法了

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

相关推荐
倒头就睡的小比特3 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼3 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
m0_547486663 天前
《数据结构教程》全套 PPT课件2026
数据结构
旖旎夜光3 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark3 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her13 天前
并查集-听课笔记
笔记·算法·并查集
码流子3 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven3 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark3 天前
从算法设计模式看编程思维的抽象能力4
算法