【数据结构OJ题】相交链表

简介: 力扣题目——相交链表

​​​​​

原题链接:https://leetcode.cn/problems/intersection-of-two-linked-lists/description/

目录

  1. 题目描述

  2. 思路分析

  3. 代码实现

1. 题目描述

bce52756d7b63fb305b4ae3d4f718382.png

2. 思路分析

看到这道题,很容易想到的方法就是暴力求解,就是将一个链表的每个结点的地址分别和另外一个链表的每个结点的地址进行比较,如果有相等的,就说明相交了。(注意这里不能比值,因为两个不同的结点值有可能一样)。但是这样的时间复杂度太高了,为O(N^2)。

这道题有一个很好的做法:

先计算出两个链表的长度,让长的链表先走相差的长度,然后两个链表同时走,直到遇到相同的结点,即为第一个公共结点。

我们定义了四个变量curA,curB,lenA,lenB。

我们用结构体指针curA遍历链表A,用结构体指针curB遍历链表B。

lenA表示链表A的长度lenB表示链表B的长度

用while循环通过遍历分别得到了链表A和B的长度。

我们判断尾结点是否相等,如果尾结点相等,说明两个链表一定相交!!!

(我们看下图,如果两个链表相交,那么从这个相交的结点(包括这个交点)之后的结点,在两个链表中都是相等的。所以尾结点相等,说明两个链表一定相交。)
image.png
如果两个链表不相交(curA!=curB),我们直接返回空指针NULL

如果两个链表相交,我们先让长的链表走两个链表长度的差距步(gap)。因为不知道两个链表哪个长,所以我们使用了abs()函数,差距步gap就是abs(lenA-lenB)

之后我们又引入了两个结构体指针longListshortList分别指向长链表短链表的头。这里用了if语句判断,先假设某个链表是长链表,如果不是,就让它等于短链表。

然后我们用一个while循环让长链表走差距步while(gap--))。
image.png

然后让longList和shortList这两个结构体指针同时走,找交点,找到交点时结束循环。

最后返回longList即可。

3. 代码实现

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
   
    struct ListNode *curA=headA,*curB=headB;
    int lenA=1,lenB=1;
    //计算链表长度
    while(curA->next)
    {
   
        curA=curA->next;  
        ++lenA;
    }
    while(curB->next)
    {
   
        curB=curB->next;
        ++lenB;
    }
    //不相交
    if(curA!=curB)
        return NULL;
    int gap=abs(lenA-lenB);
    struct ListNode *longList=headA,*shortList=headB;
    if(lenA<lenB)
    {
   
        longList=headB;
        shortList=headA;
    }
    //长的先走差距步
    while(gap--)
    {
   
        longList=longList->next;
    }
    //同时走找交点
    while(longList!=shortList)
    {
   
        longList=longList->next;
        shortList=shortList->next;
    }
    return longList;
}

image.png

相关文章
|
8月前
|
机器学习/深度学习 算法
24. 两两交换链表中的节点, 19.删除链表的倒数第N个节点 ,面试题 02.07. 链表相交
1. **两两交换链表中的节点**:通过引入虚拟头结点,使所有节点都能采用统一的交换逻辑,避免对头结点单独处理。 2. **删除链表的倒数第N个节点**:利用双指针技巧,让快慢指针保持N个节点的距离,当快指针到达末尾时,慢指针正好指向待删除节点的前一个节点。 3. **链表相交**:先计算两链表长度并调整起点,确保从相同距离末尾的位置开始遍历,从而高效找到相交节点或确定无交点。 以上方法均在时间复杂度和空间复杂度上进行了优化,适合用于理解和掌握链表的基本操作及常见算法设计思路。
|
存储 算法 Perl
数据结构实验之链表
本实验旨在掌握线性表中元素的前驱、后续概念及链表的建立、插入、删除等算法,并分析时间复杂度,理解链表特点。实验内容包括循环链表应用(约瑟夫回环问题)、删除单链表中重复节点及双向循环链表的设计与实现。通过编程实践,加深对链表数据结构的理解和应用能力。
264 4
|
存储 机器学习/深度学习 算法
C 408—《数据结构》算法题基础篇—链表(下)
408考研——《数据结构》算法题基础篇之链表(下)。
446 30
|
存储 算法 C语言
C 408—《数据结构》算法题基础篇—链表(上)
408考研——《数据结构》算法题基础篇之链表(上)。
622 25
☀☀☀☀☀☀☀有关栈和队列应用的oj题讲解☼☼☼☼☼☼☼
### 简介 本文介绍了三种数据结构的实现方法:用两个队列实现栈、用两个栈实现队列以及设计循环队列。具体思路如下: 1. **用两个队列实现栈**: - 插入元素时,选择非空队列进行插入。 - 移除栈顶元素时,将非空队列中的元素依次转移到另一个队列,直到只剩下一个元素,然后弹出该元素。 - 判空条件为两个队列均为空。 2. **用两个栈实现队列**: - 插入元素时,选择非空栈进行插入。 - 移除队首元素时,将非空栈中的元素依次转移到另一个栈,再将这些元素重新放回原栈以保持顺序。 - 判空条件为两个栈均为空。
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】单链表的基本运算(头歌实践教学平台习题)【合集】
本内容介绍了单链表的基本运算任务,涵盖线性表的基本概念、初始化、销毁、判定是否为空表、求长度、输出、求元素值、按元素值查找、插入和删除数据元素等操作。通过C++代码示例详细解释了顺序表和链表的实现方法,并提供了测试说明、通 - **任务描述**:实现单链表的基本运算。 - **相关知识**:包括线性表的概念、初始化、销毁、判断空表、求长度、输出、求元素值、查找、插入和删除等操作。 - **测试说明**:平台会对你编写的代码进行测试,提供测试输入和预期输出。 - **通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了测试通过后的预期输出结果。 开始你的任务吧,祝你成功!
588 5
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
453 5
|
存储 SQL 算法
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
|
存储 SQL 算法
LeetCode 题目 86:分隔链表
LeetCode 题目 86:分隔链表