【数据结构】C语言算法练习题——相交链表

题目链接:

力扣icon-default.png?t=M4ADhttps://leetcode.cn/problems/intersection-of-two-linked-lists/description/

解题思路:

思路一:

把 A 链表中的所有结点的地址拿去都与 B 链表去比较,注意不能比较 值 ,要比较结点的地址,

因为不可能有俩个结点的地址是相同的,如果相同,则一定为同一结点。

而且即使俩个单链表中的俩个结点不相交,它们的值也可能会相等,

所以如果比较值的话会出现误差

注意:

俩个链表或者多个链表可以相交于一个结点,

但是从这个相交结点开始后面所有结点的地址都相同,因为一个结点只能存放一个地址,即如下

图:

但是这种算法的时间复杂度是 O(n^2),不符合题目要求。

思路二:

可以从尾结点入手,

因为根据相交链表的特点: 从相交结点开始后面所有的结点的地址都相同。

所以可以判断俩个链表的尾结点的地址是否相同来判断俩个链表是否存在相交的结点。

要先求出俩个链表的长度,在求长度的过程中就可以判断俩个链表的尾结点的地址是否相同,

从而判断出俩个链表是否有相交结点。让其中链表长度最长的链表开始从前往后走 “ 差距步 ” ,即

从前往后走 ” 长度差 “ 步。

而当其中长度较长的一个链表中走到差距步时,

需要将其指向的结点的地址与另一条长度较为短的链表的第一个结点的地址相比较,

如果不相等,则俩个链表同时从当前地址向后继续遍历

参考代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) 
{
    struct ListNode *cura , *curb;
    cura = headA;
    curb = headB;
    int lena = 0 , lenb = 0;
    
    while (cura)
    {
        ++lena;
        cura = cura->next;
    }

    while (curb)
    {
        ++lenb;
        curb = curb->next;
    }

    //判断俩个链表的尾结点是否相同,即判断俩个链表是否有相交结点
    if (cura != curb)
    {
        return NULL;
    }
    
    //下面是属于相交的情况,接下来就是要判断俩个链表谁的长度长,然后求其第一个交点
    //所以需要 if...else... 语句去判断谁的长度长,谁的长度短
    //但是针对于这种情况,有以下这种技巧可以省略大量冗余的代码
    //先假设一个链表的长度最长,另一个链表的长度最短,然后紧接着用 if 语句去判断自己是否假设错了
    struct ListNode *longlist = headA , *shortlist = headB;
    if (lena < lenb)
    {
        longlist = headB;
        shortlist = headA;
    }
    //当执行完上述代码则已经将长的链表归到了longlist中,将短的链表归到shortlist中

    int gap = abs(lena - lenb);//其中abs()是用来求其绝对值的

    //接下来就是要让长的链表从前往后走 “差距步”
    while (gap--)
    {
        longlist = longlist->next;
    }
    //接下来是要让俩个链表同时向后进行遍历(在还没有遇到相交结点的情况下)
    while (longlist != shortlist)
    {
        longlist = longlist->next;
        shortlist = shortlist->next;
    }

    return longlist;//也可以返回 shortlist
    
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值