链表面试题7之相交链表

来了来了,这道题才是值得我们奇思妙想的题,链接在下面。

160. 相交链表 - 力扣(LeetCode)

看完题目一脸懵吗,没关系,我们还得看示例

还是一脸懵怎么办?? 两个链表相交的方式有几种?

我们再来仔细看一下这道题

这里我们就看到了,可能出现三种形式的相交,那我们就要在想一下,这三种情况下,我们应该怎么去判断这两个链表是相交的。

为什么是找地址而不是比值呢?我们就把图放大来看看:

这里我们看到,困扰我们的,是两个链表不等长,就像示例1中,即使我们的比值一样了,但是所在位置不一样,不一定是相交。所以在这里,还是用我们的地址来判断最为稳妥。

好了,那我们来试试看,能不能用双指针法来解决,但是你会很直观发现不可行,因为链表长度是不相同的。 那怎么解决呢?

那我们就要找两个链表的长度差了,这里不是链表长短不一样阻碍了我吗?那我干脆让他等长好了。让长的链表先走两个链表之间的长度差次。为什么可以这样做?看图。无论我这个链表多长,那我相交节点前的两个链表肯定有一个节点是对齐的。

这里放一下如何计算长度差:

cs 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    //计算两个链表长度
    ListNode* pa = headA , *pb = headB;
    int sizeA = 0,sizeB = 0;
    while(pa){
        ++sizeA;
        pa = pa->next;
    }
    while(pb)
    {
        ++sizeB;
        pb = pb->next;
    }
    //计算长度差 -- 绝对值(可以使用函数abs)
    int gap = abs(sizeA - sizeB);
 
    //找大小链表 -- 让大链表走gap 步
    ListNode* longList = headA;
    ListNode* shortList = headB;
    if(sizeA < sizeB){
        longList = headB;
        shortList = headA;
    }
    while(gap--)
    {
        longList = longList->next;
    }
    //遍历链表 -- 找相交结点
    //存在相交结点
    while(longList){
        if(longList == shortList){
            return longList;
        }
        longList = longList->next;
        shortList = shortList->next;
    }
    //不存在相交结点
    return NULL;
 
}

这就是我们的第一种方法:计算长度

第二种方法:走过彼此的路

除了计算链表长度外,我们还可以利用 两链表长度和相等 的性质来使得两个遍历指针同步

具体做法是:先遍历其中一个链表,当到底末端后跳到另一链表,最后

若两链表没有公共结点,那么两个链表指针都会走过s1+s2个结点,同时到达两链表末尾

若有公共结点,由于最后会同时走到两链表终点,所以倒退回去,两个指针一定会在第一个公共结点处相遇

可以自己在图里跳一遍!利用的就是长度差,一个快一个慢,但是最后走的路都一样,到达终点前的最后一步也一样!!非常奇妙

当然,若两链表等长,那确实不会跳到另一链表,不过链表等长本身指针就是同步的,同样也能找到公共结点

代码量很小,不过需要细致的观察。

cs 复制代码
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
        struct ListNode *p, *q;

        for (p = headA, q = headB; p != q; ){
            if (p != NULL)
                p = p->next;
            else p = headB;
            if (q != NULL)
                q = q->next;
            else q = headA;
        }

        return p;
}

好了,这道题就讲到这里

如果你觉得对你有帮助,可以点赞关注加收藏,感谢您的阅读,我们下一篇文章再见。

一步步来,总会学会的,首先要懂思路,才能有东西写。

相关推荐
多吃蔬菜!!!2 小时前
排序算法C语言实现
数据结构
零叹2 小时前
篇章六 数据结构——链表(二)
数据结构·链表·linkedlist
CM莫问2 小时前
<论文>(微软)WINA:用于加速大语言模型推理的权重感知神经元激活
人工智能·算法·语言模型·自然语言处理·大模型·推理加速
计信金边罗4 小时前
是否存在路径(FIFOBB算法)
算法·蓝桥杯·图论
MZWeiei4 小时前
KMP 算法中 next 数组的构建函数 get_next
算法·kmp
Fanxt_Ja5 小时前
【JVM】三色标记法原理
java·开发语言·jvm·算法
绿荫阿广5 小时前
互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(五):使用.NET为树莓派开发Wifi配网功能
c#·.net
luofeiju5 小时前
行列式的性质
线性代数·算法·矩阵
緈福的街口6 小时前
【leetcode】347. 前k个高频元素
算法·leetcode·职场和发展
-qOVOp-6 小时前
408第一季 - 408内容概述
数据结构