链表相交><链表分割 || 又是快乐的一天

快乐学习每一天



一、链表相交


给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
例如:
在这里插入图片描述

1.思路分析

链表相交,那就是两个链表的某个节点相同,指向了同一个地址。基本上有两个思路:
思路1: 直接暴力求解(穷举法) \color{red}{直接暴力求解(穷举法)} 直接暴力求解(穷举法),依次取A链表中的节点和B链表的所有节点进行比较,如果遇到相同的节点,那就是相交。这个方法的时间复杂度O(N^2)。
思路2: 我们直接来遍历两个链表,如果尾节点相同,那么就是相交的 \color{red}{我们直接来遍历两个链表,如果尾节点相同,那么就是相交的} 我们直接来遍历两个链表,如果尾节点相同,那么就是相交的。因为我们还得返回相交的节点,所以还得想办法。
在这里插入图片描述
如果在相交前的节点数相同,那么我们可以直接分别往后走,相同的就是要找的节点。如果不同的话,因为前面我们遍历了链表,这里就可以求出它的长度,求出两链表的差,让长链表先走几步,然后再一起走,这样岂不是大功告成。

2.上手实验

代码示下:

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode*tailA,*tailB;
    int lena=1,lenb=1,m=0;//初始1是因为找尾是tail->next
    tailA=headA;
    tailB=headB;
    while(tailA->next)//找A链表的尾
    {
        lena++;
        tailA=tailA->next;
    }
    while(tailB->next)//找B尾
    {
        lenb++;
        tailB=tailB->next;
    }
    m=abs(lena-lenb);//求出相差的
    //找相同节点
    if(tailA!=tailB)
    {
        return NULL;
    }
    //相同则让长的链表先走相差的步数
   struct ListNode*longlist=headA,*shortlist=headB;
   if(lena<lenb)
   {
       longlist=headB;
       shortlist=headA;
   }
        while(m--)//让长的先走
        {
            longlist=longlist->next;
        }
        //然后同时往后走
        while(shortlist!=longlist)
        {
            longlist =longlist->next;
            shortlist=shortlist->next;
        }
        return longlist;
    }

这题就这样结束了,对于暴力求解想必大家都很清楚,我就不多赘述了。下一题来看链表分割。

二、链表分割

现有一链表的头指针 ListNode pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。*

1.分析题意

这道题目的意思就是以x为基准进行分割,且不能改变原本的顺序。我们用图画来帮助理解。
在这里插入图片描述

2.明析思路

比较简单的思路是开两个链表出来,一个放大的,一个放小的,最后再把两个链表连在一起。
在这里插入图片描述
最后要记得将自己开出来的哨兵卫free掉最后一个节点的next要指向NULL,不然就陷入死循环了。

代码如下:

ListNode* partition(ListNode* pHead, int x) {
        // write code here
        //重新开两个链表
        struct ListNode*lesshead,*lesstail,*greaterhead,*greatertail;
        lesshead=lesstail=(struct ListNode*)malloc(sizeof(struct ListNode));
        lesstail->next=NULL;
        greaterhead=greatertail=(struct ListNode*)malloc(sizeof(struct ListNode));
        greatertail->next=NULL;
        struct ListNode*cur=pHead;
        while(cur)//将不同类别的节点分好
        {
            if(cur->val<x)
            {
                lesstail->next=cur;
                lesstail=cur;
            }
            else
            {
                greatertail->next=cur;
                greatertail=cur;
            }
            cur=cur->next;
        }
        //链接
        lesstail->next=greaterhead->next;//不是指向greaterhead
        greatertail->next=NULL;
       struct ListNode* newhead=lesshead->next;
       free(lesshead);
       free(greaterhead);
        return newhead;
    }
};

对于链表的题目,首先大家还是画画图比较好,帮助理解,理清思路再去写代码。今天就到这里了,希望大家三连支持。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值