每日一题---OJ题: 相交链表

片头

嗨! 小伙伴们,大家好! 今天我们来一起学习这道OJ题---相交链表,准备好了吗? Ready Go! ! !

emmm,看这道题好像不怎么难,我们一起画图分析分析

上图中,A链表有5个结点,分别为 a1,a2,c1,c2,c3 ; B链表有6个结点,分别为 b1,b2,b3,c1,c2,c3 ; A链表和B链表在c1结点相交

怎么做这道题呢? 第一种思路就是暴力穷举,也是一种比较容易想到的办法

思路一: 让A链表的每一个结点依次跟B链表中的结点进行比较,如果有相等就是相交,第一个相等就是交点。

代码如下:

复制代码
 typedef struct ListNode ListNode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
        ListNode* pA = headA;   //定义一个指向A链表的指针
        ListNode* pB = headB;   //定义一个指向B链表的指针

        //让A链表的每一个结点依次和B链表中的结点进行比较
        for(pA = headA; pA != NULL; pA = pA->next){
            for(pB = headB; pB != NULL; pB = pB->next){
                if(pA == pB){   //如果有相等就是相交
                    return pA;  //第一个相等就是交点
                }
            }
        }
        return NULL;            //如果没有相交,返回NULL
} 

我们把代码放到leetcode上面,显示通过

那还没有另外一种思路呢? 肯定有,且听我慢慢道来~

思路二: 1. 判断是否相交先找尾结点,尾结点的地址相同就相交; 2.找交点 长的链表先走长度差,再同时走找交点(第一个地址相同的就是交点)。

判断是否相交的代码如下:(因为后面我们需要知道长度差 ,因此在寻找尾结点的同时就计算链表的长度,效率更高)

复制代码
        ListNode* pA = headA;       //定义pA指针,指向A链表的头结点
        ListNode* pB = headB;       //定义pB指针,指向B链表的头结点

        int lenA = 0;               //A链表的长度
        while(pA->next != NULL)     //寻找A链表的尾结点
        {
            pA = pA->next;          //如果不是尾结点,pA往后走一步
            lenA++;                 //lenA的长度自增一次
        }
        lenA = lenA+1;              //别忘了加上尾结点

        int lenB = 0;                //B链表的长度
        while(pB->next != NULL)      //寻找B链表的尾结点
        {
            pB = pB->next;           //如果不是尾结点,pB往后走一步
            lenB++;                  //lenA的长度自增一次
        }
        lenB = lenB+1;               //别忘了加上尾结点

        if(pA != pB){                //如果尾结点不相同,说明两个链表不会相交
            return NULL;             //返回NULL
        }

接下来就是尾结点相同,说明两个链表相交,我们一起来找交点

部分代码如下:

复制代码
 //尾结点相同,说明两个链表相交,我们一起来找交点
        int gap = abs(lenA-lenB);   //abs()函数用来求绝对值

        //假设A链表的长度比B链表短
        //用变量shortList定义A链表,变量longList定义B链表
        ListNode* shortList = headA;
        ListNode* longList = headB;

        //如果A链表的长度比B链表长
        if(lenA > lenB)
        {
            longList = headA;  //变量longList定义A链表
            shortList = headB;//用变量shortList定义B链表,
        }

        //长的链表先走长度差
        while(gap--){
            longList = longList->next;
        }
        //再同时走找交点
        while(longList != shortList){
            longList = longList->next;
            shortList = shortList->next;
        }
        //找到交点了,返回结点
        return longList;

OK,这道题被我们解决了,整体代码如下:

复制代码
typedef struct ListNode ListNode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
        ListNode* pA = headA;       //定义pA指针,指向A链表的头结点
        ListNode* pB = headB;       //定义pB指针,指向B链表的头结点

        int lenA = 0;               //A链表的长度
        while(pA->next != NULL)     //寻找A链表的尾结点
        {
            pA = pA->next;          //如果不是尾结点,pA往后走一步
            lenA++;                 //lenA的长度自增一次
        }
        lenA = lenA+1;              //别忘了加上尾结点

        int lenB = 0;                //B链表的长度
        while(pB->next != NULL)      //寻找B链表的尾结点
        {
            pB = pB->next;           //如果不是尾结点,pB往后走一步
            lenB++;                  //lenA的长度自增一次
        }
        lenB = lenB+1;               //别忘了加上尾结点

        if(pA != pB){                //如果尾结点不相同,说明两个链表不会相交
            return NULL;             //返回NULL
        }

        //尾结点相同,说明两个链表相交,我们一起来找交点
        int gap = abs(lenA-lenB);   //abs()函数用来求绝对值

        //假设A链表的长度比B链表短
        //用变量shortList定义A链表,变量longList定义B链表
        ListNode* shortList = headA;
        ListNode* longList = headB;

        //如果A链表的长度比B链表长
        if(lenA > lenB)
        {
            longList = headA;  //变量longList定义A链表
            shortList = headB;//用变量shortList定义B链表,
        }

        //长的链表先走长度差
        while(gap--){
            longList = longList->next;
        }
        //再同时走找交点
        while(longList != shortList){
            longList = longList->next;
            shortList = shortList->next;
        }
        //找到交点了,返回结点
        return longList;
} 

哈哈哈,代码量看似很多,但是里面的逻辑一点也不复杂,只要认真分析,一定能克服难关!

片尾

今天我们学习了一道OJ题: 相交链表,里面运用到了计算链表的长度,查找链表的尾结点以及比较两个链表的结点等相关知识,希望看完这篇文章能对友友们有所帮助 ! ! !

点赞收藏加关注 ! ! !

谢谢大家 ! ! !

相关推荐
好易学·数据结构9 小时前
可视化图解算法56:岛屿数量
数据结构·算法·leetcode·力扣·回溯·牛客网
Ashlee_code14 小时前
裂变时刻:全球关税重构下的券商交易系统跃迁路线图(2025-2027)
java·大数据·数据结构·python·云原生·区块链·perl
闻缺陷则喜何志丹15 小时前
【带权的并集查找】 P9235 [蓝桥杯 2023 省 A] 网络稳定性|省选-
数据结构·c++·蓝桥杯·洛谷·并集查找
jie*15 小时前
python(one day)——春水碧于天,画船听雨眠。
开发语言·数据结构·python·算法·线性回归
草莓熊Lotso17 小时前
【LeetCode刷题指南】--数组串联,合并两个有序数组,删除有序数组中的重复项
c语言·数据结构·其他·刷题
weixin_4196583117 小时前
数据结构之B-树
java·数据结构·b树
H_HX_xL_L17 小时前
数据结构的算法分析与线性表<1>
数据结构·算法
overFitBrain17 小时前
数据结构-2(链表)
数据结构
xienda17 小时前
数据结构排序算法总结(C语言实现)
数据结构·算法·排序算法
科大饭桶17 小时前
数据结构自学Day8: 堆的排序以及TopK问题
数据结构·c++·算法·leetcode·二叉树·c