每日一题---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题: 相交链表,里面运用到了计算链表的长度,查找链表的尾结点以及比较两个链表的结点等相关知识,希望看完这篇文章能对友友们有所帮助 ! ! !

点赞收藏加关注 ! ! !

谢谢大家 ! ! !

相关推荐
wen__xvn1 小时前
基础数据结构第03天:顺序表(实战篇)
数据结构·c++·算法
聚客AI1 小时前
💡 Transformer数据管道:自定义Dataset类+智能批处理最佳实践
数据结构·人工智能·llm
爱装代码的小瓶子2 小时前
字符操作函数续上
android·c语言·开发语言·数据结构·算法
码破苍穹ovo2 小时前
回溯----5.括号生成
java·数据结构·力扣·递归
曾几何时`3 小时前
C++——位图、布隆过滤器
数据结构·算法
尤物程序猿4 小时前
深入理解ArrayList:从Java原生实现到手写一个ArrayList
java·数据结构·python
Frank_zhou5 小时前
算法-数组实战【设计链表】中等
数据结构·算法
慕婉03076 小时前
Pandas 核心数据结构详解:Series 和 DataFrame 完全指南
数据结构·pandas
夏至5606 小时前
数据结构——选择题—查漏补缺
数据结构
m0_6407435612 小时前
华为OD-2024年E卷-字符串分割[100分] -- python
数据结构·算法·华为od