单链表OJ题:LeetCode--面试题:02.04 分割链表

news2025/1/24 22:41:52

朋友们、伙计们,我们又见面了,今天给大家带来的是LeetCode面试题:02.04.分割链表

数 据 结 构:数据结构专栏
作          者:stackY、

LeetCode :LeetCode刷题训练营

 LeetCode面试题:02.04.分割链表https://leetcode.cn/problems/partition-list-lcci/

牛客网:CM11 分割链表https://www.nowcoder.com/practice/0e27e0b064de4eacac178676ef9c9d70?tpId=8&tqId=11004&rp=2&ru=/activity/oj&qru=/ta/cracking-the-coding-interview/question-ranking

目录

1.题目介绍

2.实例演示

3.解题思路

3.1不带哨兵位的头结点

3.2带哨兵位的头结点


1.题目介绍

LeetCode:

给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。

不需要 保留 每个分区中各节点的初始相对位置。

牛客网:

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

两个题目描述都差不多,但是牛客网要求不能改变相对位置,LeetCode则不在乎相对位置,那么我们就不改变相对位置了。

2.实例演示

3.解题思路

链表的分割有两种方法:

1.不带哨兵位的头结点

2.带哨兵位的头结点

(两种方法都比较简单,但是带哨兵位的话会稍微的方便一点,这里考虑到有的老铁不知道哨兵位,因此我们两种方法都来演示一下)

3.1不带哨兵位的头结点

不带哨兵位就是直接尾插法:创建两个新的链表,遍历原链表,将小于x的结点尾插到第一个链表head1中,将大于等于x的结点尾插到head2中,尾插结束后将tail2指向的next置为NULL,与原链表断开,然后将head2链接在head1的后面,这里要考虑特殊情况:

1.两个链表第一次尾插时需要注意空指针的问题。

2.在遍历完原链表之后,如果head1为空时可以直接返回head2,如果head2为空,可以直接返回head1。

3.好多老铁好奇为什么不把tail1的next也置为空,这里可以置为空也可以不置为空,因为在下面链接的时候会改变tail1的next。

 

LeetCode - 代码演示(C语言实现):

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* partition(struct ListNode* head, int x){

    //创建两个新的链表
    struct ListNode* head1 = NULL;
    struct ListNode* tail1 = NULL;
    struct ListNode* head2 = NULL;
    struct ListNode* tail2 = NULL;
    struct ListNode* cur = head;
    //遍历
    while(cur)
    {
        //小于x的插入第一个链表
        if(cur->val < x)
        {
            //第一次尾插
            if(tail1 == NULL)
            {
                head1 = tail1 = cur;
            }
            else
            {
                tail1->next = cur;
                tail1 = tail1->next;
            }
        }
        //大于或等于x的插入第二个链表
        else
        {
            if(tail2 == NULL)
            {
                head2 = tail2 = cur;
            }
            else
            {
                tail2->next = cur;
                tail2 = tail2->next;
            }
        }
        //迭代
        cur = cur->next;
    }
    //断开与原链表的联系
    if(tail2 != NULL)
    {
        tail2->next = NULL;
    }
    //判断特殊情况
    if(head1 == NULL)
    {
        return head2;
    }
    if(head2 == NULL)
    {
        return head1;
    }
    //链接第一个链表和第二个链表
    tail1->next = head2;
    return head1;
}

牛客网 - 代码实现(C++实现):

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        // write code here
        //创建两个新的链表
    ListNode* head1 = NULL;
    ListNode* tail1 = NULL;
    ListNode* head2 = NULL;
    ListNode* tail2 = NULL;
    ListNode* cur = pHead;
    //遍历
    while(cur)
    {
        //小于x的插入第一个链表
        if(cur->val < x)
        {
            //第一次尾插
            if(tail1 == NULL)
            {
                head1 = tail1 = cur;
            }
            else
            {
                tail1->next = cur;
                tail1 = tail1->next;
            }
        }
        //大于或等于x的插入第二个链表
        else
        {
            if(tail2 == NULL)
            {
                head2 = tail2 = cur;
            }
            else
            {
                tail2->next = cur;
                tail2 = tail2->next;
            }
        }
        //迭代
        cur = cur->next;
    }
    //断开与原链表的联系
    if(tail2 != NULL)
    {
        tail2->next = NULL;
    }
    //判断特殊情况
    if(head1 == NULL)
    {
        return head2;
    }
    if(head2 == NULL)
    {
        return head1;
    }
    //链接第一个链表和第二个链表
    tail1->next = head2;
    return head1;
    }
};

3.2带哨兵位的头结点

带哨兵位的头结点相比较于不带哨兵位的头结点的方法就略显简便,不需要考虑太多的NULL指针的问题,我们依旧采用的是直接尾插法:创建两个新的链表,遍历原链表,将小于x的结点尾插到第一个链表head1中,将大于等于x的结点尾插到head2中,尾插结束后将head2指向的next置为NULL,与原链表断开,然后将head2链接在head1的后面,这里就不需要考虑空指针的问题,直接尾插,尾插结束之后,不能直接将head2链接在tail1的后面,需要将head2的next链接,注意:哨兵位的头节点是动态开辟的,所以要释放掉,因此还要将链接之后的链表再链接在原链表的头上面,释放掉两个有哨兵位的链表:

 LeetCode - 代码演示(C语言实现):

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* partition(struct ListNode* head, int x){
    struct ListNode* head1, *tail1, *head2, *tail2;
    //创建带哨兵位的头结点
    head1 = tail1 = (struct ListNode*)malloc(sizeof(struct ListNode));
    head2 = tail2 = (struct ListNode*)malloc(sizeof(struct ListNode));
    
    struct ListNode* cur = head;
    while(cur)
    {
        //小的链接在第一个链表
        if(cur->val < x)
        {
            tail1->next = cur;
            tail1 = tail1->next;
        }
        else
        {
            tail2->next = cur;
            tail2 = tail2->next;
        }
        //迭代
        cur = cur->next;
    }
    //断开与原链表的联系
    tail2->next = NULL;
    //链接两个新的链表
    tail1->next = head2->next;
    //将新链表链接在原来的头结点上面
    head = head1->next;
    //释放
    free(head1);
    free(head2);
    
    return head;
}

牛客网 - 代码实现(C++实现):

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        // write code here
        ListNode* head1, *tail1, *head2, *tail2;
    //创建带哨兵位的头结点
    head1 = tail1 = (ListNode*)malloc(sizeof(ListNode));
    head2 = tail2 = (ListNode*)malloc(sizeof(ListNode));
    
    struct ListNode* cur = pHead;
    while(cur)
    {
        //小的链接在第一个链表
        if(cur->val < x)
        {
            tail1->next = cur;
            tail1 = tail1->next;
        }
        else
        {
            tail2->next = cur;
            tail2 = tail2->next;
        }
        //迭代
        cur = cur->next;
    }
        //断开与原链表的联系
        tail2->next = NULL;
        //链接两个新的链表
        tail1->next = head2->next;
        //将新链表链接在原来的头结点上面
        pHead = head1->next;
        //释放
        free(head1);
        free(head2);
        
        return pHead;
    }
};

今天的博客就分享到这里,喜欢的老铁留下你的三连,感谢感谢!我们下期再见!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/521524.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

H5微信授权登录弹窗提示

如下图&#xff1a;用户授权登录前&#xff0c;先通过静默授权&#xff0c;拿到token&#xff0c;展示部分信息&#xff0c;用户通过授权后拿到头像昵称&#xff0c;该弹窗让用户有个比较好的体验 1、标签 <template><!--遮罩--><view v-if"showAuth"…

MD-MTSP:遗传算法GA求解多仓库多旅行商问题(提供MATLAB代码,可以修改旅行商个数及起点)

一、多仓库多旅行商问题 多旅行商问题&#xff08;Multiple Traveling Salesman Problem, MTSP&#xff09;是著名的旅行商问题&#xff08;Traveling Salesman Problem, TSP&#xff09;的延伸&#xff0c;多旅行商问题定义为&#xff1a;给定一个&#x1d45b;座城市的城市集…

开发一个自定义“套壳“浏览器的开源方案

一.项目概述 二.技术选型 三.项目介绍 1.项目地址:​​​​​​https​​​​​​://github.com/keyxh/TLC_Browers 2.项目目录介绍: 3.项目后期 开发语言:VB6 浏览器内核:webview2 项目目的:在vb6调用h5&#xff0c;实现自定义的浏览器 参考资料: https://github.com…

从 Spring 的创建到 Bean 对象的存储、读取

目录 创建 Spring 项目&#xff1a; 1.创建一个 Maven 项目&#xff1a; 2.添加 Spring 框架支持&#xff1a; 3.配置资源文件&#xff1a; 4.添加启动类&#xff1a; Bean 对象的使用&#xff1a; 1.存储 Bean 对象&#xff1a; 1.1 创建 Bean&#xff1a; 1.2 存储 B…

BUUCTF--reverse1,reverse2--WP

文章目录 一.BUUCTF--reverse1二.BUUCTF--reverse2 一.BUUCTF–reverse1 这道题目也是非常简单&#xff0c;主要考察IDA Pro的使用&#xff0c;分析代码&#xff1a; 发现是64位exe&#xff0c;直接拖到IDA Pro中&#xff0c;发现没有找到主函数&#xff1a; 那就直接ShiftF12…

【操作符详解 2023-05-13】

#include <stdio.h>int main() {int a 1;int b 2;int c (a > b, a b 10, a, b a 1);//逗号表达式printf("%d\n", a);printf("%d\n", b);printf("%d\n", c);return 0; }int main() {int arr[10] { 1,2,3,4,5 };// …

等差数列求和,轻松解决力扣“K 个元素的最大和”问题

本篇博客会讲解力扣“2656. K 个元素的最大和”的解题思路&#xff0c;这是题目链接。 先来审题&#xff1a; 以下是输出示例&#xff1a; 以下是提示&#xff1a; 本题有2种思路&#xff0c;一种是直接按照题目所说的方式模拟&#xff0c;另一种是直接使用数学公式。 显然…

STM32f103时钟树详解

一、概述 stm32有四种时钟信号源&#xff0c;HSE(高速外部时钟)、HSI&#xff08;高速内部时钟&#xff09;、LSE&#xff08;低速外部时钟&#xff09;、LSI&#xff08;低速内部时钟&#xff09;。HSE通常接8M晶振&#xff0c;经由内部分频和倍频&#xff0c;最大可得到72MH…

荔枝派Zero(全志V3S)驱动开发之RGB LED灯

文章目录 前言一、硬件连接二、文件 IO 方式操作 GPIO三、编写驱动四、编写应用程序1、V1 版本&#xff0c;实现蓝灯亮灭2、V2 版本&#xff0c;实现蓝灯闪烁 五、编译六、运行测试七、资源自取方式1&#xff1a;github 链接方式2&#xff1a;百度网盘 前言 一、硬件连接 查看…

绝~ 阿里内部“Java进阶必备宝典”,理论到实战,一键通关

前言 作为一名Java方向的程序员&#xff0c;打好夯实的基础是非常重要的&#xff0c;现在大厂面试对于程序员基础知识的掌握考察也越来越严格&#xff0c;虽然说现在技术更新比较快&#xff0c;但基础扎实才能够更深入的去理解每一个知识技术点。 关于Java程序员如何筑基&…

实现“省市县的联动”

分析&#xff1a;实现这一功能需要发送三次Ajax请求 1.第一次请求&#xff1a;是页面加载完毕之后&#xff0c;发送一次Ajax请求&#xff0c;查询出所有的省级单位&#xff0c;将这些查询结果展示在<select>标签中。 2.第二次请求&#xff1a;当所选省级单位发生变化的时…

java工程构建时带上分支,commit等信息

背景&#xff1a; 线上部署的jar包&#xff08;不管是直接运行jar包&#xff0c;还是通过容器运行的jar&#xff09;有时出现问题时需要查看源代码&#xff0c;需要知道该jar包是从哪个分支、哪个commit、哪个时间打包的。 有了这些信息能更好辅助我们分析判断问题。 这里以gr…

【.NET基础加强第九课--事件】

.NET基础加强第九课--事件 Event 关键字委托,事件对比举例: 音乐播放事件用户对象&#xff0c;登录程序集反射 Event 关键字 委托,事件对比 委托是一种数据类型&#xff0c;可以用调用。 事件:对象&#xff08;对委托的一种封闭装&#xff09;。只能在类内部&#xff0c;只能…

基于Java的企业员工管理系统的设计与实现(论文+源码)_kaic

基于Java的企业员工管理系统的设计与实现 摘 要 随着电子信息的飞速发展&#xff0c;计算机已经融入到了生活的各个方面&#xff0c;越来越多的企业开始使用电子计算机来对企业进行管理&#xff0c;信息化的时代已经到来&#xff0c;各个企业无论大小都需要一个信息化的管理系…

模拟实现qsort函数(采用冒泡排序的方式)

前言&#xff1a; 之前我在C语言&#xff1a;指针详解【进阶】后篇中提到了qsort函数,qsort函数作为一个库函数&#xff0c;在我们日常的代码编写中可能会用到&#xff0c;在上面提到的文章中我们也进行使用了这个函数&#xff0c;大家也了解了一些这个函数的使用方法&#xff…

English Learning - L3 作业打卡 Lesson1 Day4 2023.5.8 周一

English Learning - L3 作业打卡 Lesson1 Day4 2023.5.8 周一 引言&#x1f349;句1: They may say they are red hot about something unfair.成分划分弱读连读爆破语调 &#x1f349;句2: When they are red hot, they are very angry about something.成分划分弱读连读爆破语…

【Ansys】mechanical和fluent求解器中使用的迭代方法-待补充

一、mechanical求解器 这个求解器&#xff0c;在网上很容易查到&#xff0c;迭代求解时用的就是牛顿-拉夫逊方法&#xff08;Newton-Raphson&#xff09;。 这是因为牛顿法求解非线性问题非常优秀。 而mechanical使用这个方法就能实现对几何非线性、材料非线性、接触非线性、…

Java入门和背景知识

文章目录 &#x1f525;常见编程语言介绍&#x1f525;Java 发展史&#x1f525;Java 的核心优势&#x1f525;Java 各版本的含义&#x1f525;Java 的特性和优势&#x1f525;Java 运行机制&#x1f525;JVM、JRE 和 JDK&#x1f525;Java 开发环境搭建&#x1f525;openJDK 和…

网络购物商场系统的设计与实现(论文+源码)_kaic

网络购物商场系统 摘 要 近年来&#xff0c;随着网络购物的兴起和普及&#xff0c;针对该市场需求开发一款在线购物系统是大势所趋。和实体店对比&#xff0c;在线购物系统商品种类齐全&#xff0c;价格优惠、还能够送货上门等优势。在此类系统中&#xff0c;用户能够在网上…

潍坊这一城市商业综合体有奖征名

云创金谷项目商业购物中心名称及IP形象征集开始啦&#xff01;&#xff01;你有什么好想法&#xff1f;快来参与吧&#xff01;&#xff01; 云创金谷&#xff0c;是奎文区重点打造的城市更新代表力作&#xff0c;位于文化路以东、新华路以西&#xff0c;北宫街以北、卧龙东街以…