OJ:【图解思路+源码】相交链表 |【C语言】[ 数据结构 ]

相交链表

OJ:【图解思路+源码】相交链表 |【C语言】[ 数据结构 ]_第1张图片
题目链接:160. 相交链表 - 力扣(LeetCode)

思路

  • 首先明确一点,相交链表最终一定“汇合”成“一条链表”,如上图,而绝不能呈 “x” 交叉状,因为每个结点指向唯一一个下一个结点

由此,我们可以知道,相交链表一定有同一个尾结点。
根据这个条件,我们可以有如下两种思路。

  • 思路一:暴力比对,因为不知道哪一个是相交的起始结点,因此只能一个一个确认,就是说我们先拿到A链表的一个结点,然后与B链表的所有结点比对——是否是同一个结点。以此类推,知道找到相交的结点或者比对完所有的结点。显然,时间复杂度是O(N²)。
  • 思路二
    OJ:【图解思路+源码】相交链表 |【C语言】[ 数据结构 ]_第2张图片
    如上。
  1. 如果两个链表一样长,就可以一一对应的比较
  2. 怎么让链表 “一样长” 呢?
  3. 让链表 “对齐” (如上图)
  4. 那么我们需要求出链表的长度,由此得出链表gap(结点数量差)

因此,我们得出了具体的解决方案:

  • Step 1. 判断尾节点是否相等遍历两个链表,同时记录链表结点个数
if((!headA)||(!headB))  //如果链表中有任意一个为空就return NULL;
        return NULL;
struct ListNode* curA = headA, * curB = headB;//用curA和curB遍历链表

int countA = 0, countB = 0; //记录链表结点个数

while (curA->next)  
//当curA->next为空即尾节点结束循环
//虽然最后一个结点没有被记上,但是我们最终是要得到两链表之差,所以不影响
{
	countA++;
	curA = curA->next;
}
while (curB->next)
{
	countB++;
	curB = curB->next;
}
if (curA != curB) //如果尾节点不相等则两链表不相交
return NULL;
  • Step 2. 确定相交并且我们得到gap后,让两链表“对齐”让长的链表的指针先走gap步,再进行比对
int gap = abs(countA - countB);  
//abs是算绝对值的函数,头文件是#include

这里有个小技巧,定义一个长链表和短链表,这样走的时候就让长链表先走,不然就要 if、else写两个差不多的语句。

struct ListNode* longlist = headA, * shortlist = headB;
if (countB > countA)
{
    longlist = headB;
    shortlist = headA;
}
while (gap--)
{
    longlist = longlist->next;
}
  • Step 3. longlist和shortlist一起走,对应比较找出交点
while (shortlist)
{
    if (shortlist == longlist)
        return shortlist;
    shortlist = shortlist->next;
    longlist = longlist->next;
}
return NULL;

完整源码

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) 
{
    if((!headA)||(!headB))
        return NULL;
    struct ListNode *curA=headA,*curB=headB;
    int countA=0,countB=0;
    while(curA->next)
    {
        countA++;
        curA=curA->next;
    }
    while(curB->next)
    {
        countB++;
        curB=curB->next;
    }
    if(curA!=curB)
        return NULL;
        
    int gap=abs(countA-countB);
    struct ListNode* longlist=headA,*shortlist=headB;
    if(countB>countA)
    {
        longlist=headB;
        shortlist=headA;
    }
    while(gap--)
    {
        longlist=longlist->next;
    }
    
    while(shortlist)
    {
        if(shortlist==longlist)
            return shortlist;
        shortlist=shortlist->next;
        longlist=longlist->next;
    }
   return NULL;
}

你可能感兴趣的:(学习笔记,code,链表,数据结构,c语言,leetcode)