首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【LeetCode&牛客&数据结构】单链表的应用——环形链表及链表分割问题详解

【LeetCode&牛客&数据结构】单链表的应用——环形链表及链表分割问题详解

作者头像
用户11831438
发布2025-12-30 12:32:24
发布2025-12-30 12:32:24
1200
举报

前言:各位uu们,在刷题的时候,要多画图,画图有利于我们更快的思考出相应的解题思路!!!

正文

一、环形链表1

141. 环形链表 - 力扣(LeetCode)

1、题目描述
2、思路及代码

思路:设置两个指针,一个快指针,一个慢指针,快指针每次走两步,慢指针每次走一步,比较来两个指针,如果相等,则说明有环;否则没有环。

将上面思路转换成代码:

代码语言:javascript
复制
typedef struct ListNode ListNode;
bool hasCycle(struct ListNode *head) {
    ListNode* slow=head;
    ListNode* fast=head;
    while(fast!=NULL&&fast->next!=NULL)
    {
        slow=slow->next;
        fast=fast->next->next;
        if(slow==fast)
        {
            return true;
        }
    }
    return false;
}

若有uu对循环条件不清楚的,可以看一下上面的链表的中间节点思路2。

3、结论及证明

思考1:为什么快指针每次走两步,慢指针走一步可以相遇,有没有可能遇不上,请推理证明!

因此,在带环链表中慢指针走一步,快指针走两步最终⼀定会相遇。

思考2:快指针⼀次走3步,走4步,...n步行吗?

所以,不管fast每次走几步,一定会相遇。

4、其他思路

我们也可以创建数组:

二、环形链表2

142. 环形链表 II - 力扣(LeetCode)

1、题目描述

示例

2、思路及代码

思路:首先判断链表是否有环(快慢指针),快慢指针找相遇点,相遇点到入环结点的距离==头结点到入环结点的距离。

将上面的思路转换成代码:

代码语言:javascript
复制
typedef struct ListNode ListNode;
struct ListNode *detectCycle(struct ListNode *head) {
    ListNode* slow=head;
    ListNode* fast=head;
    while(fast!=NULL&&fast->next!=NULL)
    {
        slow=slow->next;
        fast=fast->next->next;
        if(slow==fast)
        {
            //说明有环,快慢指针相遇
            //相遇点到入环结点的距离==头结点到入环节点的距离
            ListNode* pcur=head;
            while(pcur!=fast)
            {
                pcur=pcur->next;
                fast=fast->next;
            }
            return fast;
        }
    }
    return false;
}
3、结论及证明

通过这题我们可以得出一个结论:

接下来,我们可以尝试证明一下这个结论

三、链表分割

链表分割_牛客题霸_牛客网

1、题目描述
2、解题思路

思路:创建两个新的头点,作为“哨兵位”,遍历原链表,比较结点中的值与x的大小,一个链表中放比x大的值,另一个链表放比x小的值,最后将这两个链表相连接,返回小的链表的头结点。

3、思路转换成代码
代码语言:javascript
复制
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
#include <cstddef>
#include <random>
class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        // write code here
        ListNode* lessHead,*lessTail;
        ListNode* greatHead,*greatTail;
        lessHead=lessTail=(ListNode*)malloc(sizeof(ListNode));
        greatHead=greatTail=(ListNode*)malloc(sizeof(ListNode));
        //遍历链表,比较大小
        //大的放大链表中,小的放小链表中
        ListNode* pcur=pHead;
        while(pcur)
        {
            if(pcur->val<x)
            {
                lessTail->next=pcur;
                lessTail=lessTail->next;
            }
            else {
            greatTail->next=pcur;
            greatTail=greatTail->next;
            }
            pcur=pcur->next;
        }
        //链接两个链表
        lessTail->next=greatHead->next;
        greatTail->next=NULL;
        ListNode* ret=lessHead->next;
        free(lessHead);
        free(greatHead);
        lessHead=NULL;
        greatHead=NULL;
        return ret;
    }
};

注意:在书写上面代码时,有个地方需要注意。当最后连接两个链表后,需要将存放较大值链表的尾节点的next指针置为空,如果不置为空,会导致无限循环打印,最终导致代码报错。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-09-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 正文
    • 一、环形链表1
      • 1、题目描述
      • 2、思路及代码
      • 3、结论及证明
      • 4、其他思路
    • 二、环形链表2
      • 1、题目描述
      • 2、思路及代码
      • 3、结论及证明
    • 三、链表分割
      • 1、题目描述
      • 2、解题思路
      • 3、思路转换成代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档