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

点赞收藏加关注 ! ! !

谢谢大家 ! ! !

相关推荐
代码雕刻家25 分钟前
数据结构-3.9.栈在递归中的应用
c语言·数据结构·算法
Kalika0-02 小时前
猴子吃桃-C语言
c语言·开发语言·数据结构·算法
代码雕刻家2 小时前
课设实验-数据结构-单链表-文教文化用品品牌
c语言·开发语言·数据结构
小字节,大梦想3 小时前
【C++】二叉搜索树
数据结构·c++
我是哈哈hh4 小时前
专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结
服务器·数据结构·c++·算法·机器学习·深度优先·剪枝
丶Darling.4 小时前
LeetCode Hot100 | Day1 | 二叉树:二叉树的直径
数据结构·c++·学习·算法·leetcode·二叉树
labuladuo5205 小时前
Codeforces Round 977 (Div. 2) C2 Adjust The Presentation (Hard Version)(思维,set)
数据结构·c++·算法
Indigo_code5 小时前
【数据结构】【链表代码】合并有序链表
数据结构·windows·链表
jiyisuifeng19915 小时前
代码随想录训练营第54天|单调栈+双指针
数据结构·算法
我言秋日胜春朝★5 小时前
【C++】红黑树
数据结构