【数据结构】链表OJ:力扣160. 相交链表

最近这几篇内容都有关链表,接下来几篇内容会分享一些链表的OJ题,希望对你有所帮助。

今天要分享的内容是力扣160. 相交链表:160. 相交链表 - 力扣(LeetCode)

目录

题目: 

题解


题目: 

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

图示两个链表在节点 c1 开始相交:

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构 。

自定义评测:

评测系统 的输入如下(你设计的程序 不适用 此输入):

intersectVal - 相交的起始节点的值。如果不存在相交节点,这一值为 0
listA - 第一个链表
listB - 第二个链表
skipA - 在 listA 中(从头节点开始)跳到交叉节点的节点数
skipB - 在 listB 中(从头节点开始)跳到交叉节点的节点数
评测系统将根据这些输入创建链式数据结构,并将两个头节点 headA 和 headB 传递给你的程序。如果程序能够正确返回相交节点,那么你的解决方案将被 视作正确答案 。

题解

首先要说的是链表的相交并不能像一个大叉一样

 因为如上这样的小圈中都代表着一个节点,而每个节点中只有一个结构体变量next,所以无法分开指向两个节点,所以真正的链表相交应该是如下图

 接下来探究一下链表相交的方法

1.判断尾结点是否相等,为结点相等两个链表相交;

2.找交点:分别求出链表A和链表B的长度,先让长的链表走出两个链表差距的长度,再同时走,当两个链表第一次相等时就是焦点;

以下是本题代码

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode *tailA=headA;
    struct ListNode *tailB=headB;
    int lenA=1;
    int lenB=1;
//判断两个链表是否有交点
    while(tailA->next)
    {
        tailA=tailA->next;
        ++lenA;
    }
    while(tailB->next)
    {
        tailB=tailB->next;
        ++lenB;
    }

    if(tailA!=tailB)//不相交返回空
    {
        return NULL;
    }
    
    //长链表先走差距步
    int gap=abs(lenA-lenB);
    struct ListNode *longList=headA;
    struct ListNode *shortList=headB;
    if(lenA<lenB)
    {
        longList=headB;
        shortList=headA;
    }//判断A和B的长短
    while(gap--)
    {
        longList=longList->next;
    }
    while(longList!=shortList)
    {
         longList=longList->next;
         shortList=shortList->next;
    }

    return longList;
}

 对照着代码我们一步一步来说;

以上代码的注释也非常清楚;

1.首先链表相交就要判断他们是否有交点,如果没有交点就返回NULL(空)。因为链表停止的标志是最后一个结点是否指向空,所以可以利用tailA来操作结构体指针next来判断,并且使用len来标志两个链表的长度;

2.如上解题思路,需要判断两个链表哪个长哪个短,长的先走差距步数,再一起走,再判断交点。这时就需要使用绝对值函数abs,他是用来计算绝对值的函数,这样就可以计算两个链表的差距步数;

3.最后让结点向后迭代并判断,两个链表有交点就说明指向的结点是一样的,所以可以将两个链表进行对比,用“当两个结点不相等时就像后迭代”作为判断条件,在末尾返回即可 (两个结点同时向后迭代,所以返回shortList和longlist都是正确的);

猜你喜欢

转载自blog.csdn.net/wangduduniubi/article/details/130515683