LeetCode 牛客单链表OJ题目思路分享

news2024/10/5 0:45:18

目录

  • 反转链表
  • 合并两个有序链表
  • 链表分割

反转链表

链接: link
题目描述:
在这里插入图片描述
题目思路:
方法1:改变链表链接的方向
在这里插入图片描述

方法1思路:
这力我们需要三个指针n1 n2 n3方便我们进行迭代
在这里插入图片描述
初始化n1指向NULL,n2指向第一个节点,n3指向第2个节点,下面是n1 n2 n3 3个指针移动的过程。
1、改变第一个指针n1的指向,链表反转后,第一个节点的指针域指向的是NULL,就上图来看,也就是n2->next=n1;
在这里插入图片描述
2、改变指向后,我们接下来的操作就是移动3个指针继续进行链接变向的操作。下面是如何变动三个指针的过程:
将n2的值赋给n1,n3的值赋给n2,n3再向下走一步。
在这里插入图片描述
3、下面进行的步骤就是反转链接方向:n2->next = n1。
在这里插入图片描述

上述过程就是我们反转的最核心步骤,下面是本题循环终止条件和Bug点:

这里我们要注意,本题要清楚的是,当n1指向最后一个节点的时候,循环就终止了,但是这个点并不是我们所需要的循环的终止条件,循环终止条件是n2为空指针
在这里插入图片描述
本题大致雏形就出来了,但是我们实际进行运行的时候,还会出现空指针的问题,问题的来源就在于n3
在这里插入图片描述
当n2不为空指针,并且n2此时已经指向最后一个节点时,n3已经为空指针,当n2为空指针的时候,n3也要向下走,这就造成了空指针的问题,所以我们要进行处理的是n3,n3不为空指针的时候,n3才可以继续向下走。
最后状态如下图所示:最后我们只需要返回n1就可以了
在这里插入图片描述
代码实现:

struct ListNode* reverseList(struct ListNode* head)
{
    if(head==NULL)
    {
        return NULL;
    }
    struct ListNode* n1 = NULL;
    struct ListNode* n2 = head;
    struct ListNode* n3 = head->next;
    while(n2)
    {
        //改变链表指向
        n2->next = n1;
        //迭代
        n1 = n2;
        n2 =n3;
        if(n3)//如果n3不为空,则n3向下走
        {
            n3 = n3->next;
        }
    }
    return n1;
}

方法2:依次取节点进行头插
在这里插入图片描述

方法2思路:
在这里插入图片描述
定义如上图3个指针变量,cur指向当前节点,next指向当前节点的下一个节点,rhead是链表反转之后新的头。
初始化rhead = NULL,cur = head,next = cur->next;
下面进行头插:
cur->next = rhead,rhead = cur,cur = next,next = next->next
在这里插入图片描述

以上就是本题头插的核心步骤,下面是本题循环终止条件和bug点:

当cur指向空时,循环终止,但是当cur指向空时,也会出现next空指针的问题,在cur指向最后一个节点时,next就指向空了,所以这里我们也要对next进行一下判断。

代码实现:

struct ListNode* reverseList(struct ListNode* head)
{
    if(head==NULL)
    {
        return NULL;
    }
    struct ListNode* rhead = NULL;
    struct ListNode* cur = head;
    struct ListNode* next = cur->next;
    while(cur)
    {
        cur->next = rhead;
        rhead = cur;
        cur=next;
        if(next)
        {
            next = next->next;
        }
    }
    return rhead;
}

合并两个有序链表

链接: link
题目描述:
在这里插入图片描述
题目思路:带哨兵位解法
什么是带哨兵位?

带哨兵位就是在一条链表的前面,有一个空的节点不存放任何的值,如下图:
在这里插入图片描述
动态申请1个空间的哨兵位作为新的头,之后进行链接。
1、如果List1的值比List2的值小,那么head->next就是我们合并后链表新的头,之后让List1指向下一个节点,并且tail指向刚刚被插入的节点。
与此同时如果List2的值比List1的值小,那么head->next就是我们合并后链表新的头,之后让List2指向下一个节点,并且tail指向刚刚被插入的节点。
2、有了新链表的头之后,剩下的步骤就是比较两个节点的大小,那个节点值大,就将哪个节点拿下来尾插,并且让尾指针tail指向该尾插的节点。
3、在进行不断的尾插的过程中肯定会有一条链表为空,如果是List1为空,那么直接让tail->next链接List2,否则链接List1。
注意:
1、我们还要注意一点就是,很有可能给我们的两条链表有一条是空链表,此时只需要返回那条不为空的链表就好。
2、动态申请的两个节点最后要记得释放

代码实现:

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
    if(list1==NULL)
    {
        return list2;
    }
    if(list2==NULL)
    {
        return list1;
    }
    if(list1==NULL&&list2==NULL)
    {
        return NULL;
    }
    struct ListNode* head = NULL;
    struct ListNode* tail = NULL;
    head = tail = (struct ListNode*)malloc(sizeof(struct ListNode));
    while(list1&&list2)
    {
        if(list1->val<list2->val)
        {
            tail->next = list1;
            tail=tail->next;
            list1= list1->next;
        }
        else
        {
            tail->next = list2;
            tail=tail->next;
            list2= list2->next;
        }
    }
     if(list1)
    {
        tail->next = list1;
    }
    if(list2)
    {
        tail->next = list2;
    }
    struct ListNode* del = head;
    head = head->next;
    free(del);
    return head;
}

链表分割

链接: link
题目描述:
在这里插入图片描述
题目思路:
假设给定一串链表:
在这里插入图片描述
假设x的值我们设置为3,则分割链接后就是下面的结果:
在这里插入图片描述

本题思路依然是构造两个带有哨兵位的链表,将小于3的拿下来尾插到链表1,将大于3的拿下来尾插到链表2,最后将链表2链接到链表1的后面,返回链表1的头,同时释放两个哨兵位节点。
在这里插入图片描述
注意:第二个链表的尾指针最后要置空,否则链表中会出现环。

代码实现:

class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        struct ListNode* lesshead,*lesstail,*greaterhead,*greatertail;
        lesshead = lesstail = (struct ListNode*)malloc(sizeof(struct ListNode));
        greaterhead = greatertail = (struct ListNode*)malloc(sizeof(struct ListNode));
        struct ListNode* cur = pHead;
        while(cur)
        {
            if(cur->val<x)
            {
                lesstail->next = cur;
                lesstail = lesstail->next;
            }
            else 
            {
                greatertail->next = cur;
                greatertail= greatertail->next;
            }
            cur=cur->next;
        }
        lesstail->next = greaterhead->next;
        greatertail->next = NULL;
        pHead = lesshead->next;
        free(lesshead);
        free(greaterhead);
        return pHead;
    }
};

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

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

相关文章

云原生时代崛起的编程语言Go常用标准库实战

文章目录 基础标准库简述字符串-string底层结构函数长度格式化输出 模版-templatetext/templatehtml/template 正则表达式-regexp编码-encodingBase64JSONXML 时间-time网络-netURLHTTP客户端和服务端 加密IO操作读写文件环境变量命令行 数据库排序-sort测试和基准测试 基础标准…

OpenLDAP安装报错

tip:基于centos7&#xff0c;OpenLDAP使用2.4.44版本 只要有succeeded就可以。error可以忽略 配置base.ldif文件&#xff0c;下面的空行是必须的。 dn: dcts,dccom o: ts com dc: ts objectClass: top objectClass: dcObject objectclass: organizationdn: cnManager,dcts,d…

leveldb自定义env

leveldb自定义env 未完待续。。。 由于项目需求&#xff0c;需要自定义LevelDB的env&#xff0c;也就是以块接口实现env中各个文件接口&#xff0c;在网上没找到类似的代码&#xff0c;就打算自己参照util/env_posix.cc实现一个简单的demo&#xff0c;等到功能实现差不多的时候…

ADRV9002官方例程开发过程中遇到的问题

开发环境&#xff1a;Vivado2021.2 HDL版本&#xff1a;hdl_2021_r2 GitHub - analogdevicesinc/hdl at hdl_2021_r2 no-OS版本&#xff1a;no_OS-2021_R2 GitHub - analogdevicesinc/no-OS at 2021_R2 &#xff08;PS&#xff1a;也可以用Vivado2019.1开发&#xff0c…

【漏洞复现】Joomla未授权访问漏洞(CVE-2023-23752)

文章目录 前言声明一、漏洞简介二、影响版本三、环境搭建四、漏洞分析五、漏洞复现六、修复建议前言 Joomla是一套全球知名的内容管理系统(CMS),其使用PHP语言加上MySQL数据库所开发,可以在Linux、Windows、MacOSX等各种不同的平台上运行。 声明 本篇文章仅用于漏洞复现与…

华为OD机试真题-密码强度等级【2023】【JAVA】

一、题目描述 密码按如下规则进行计分&#xff0c;并根据不同的得分为密码进行安全等级划分。 1、密码长度&#xff1a; 5 分: 小于等于4 个字符 10 分: 5 到7 字符 25 分: 大于等于8 个字符 2、字母&#xff1a; 0 分: 没有字母 10 分: 密码里的字母全都是小&#xff08;…

电脑硬盘磁盘不小心被格式化了?如何一键恢复操作教程

Easyrecovery是一款功能齐全的数据恢复软件&#xff0c;恢复内容包括&#xff1a;硬盘数据恢复、手机数据恢复、U盘数据恢复、Mac数据恢复、恢复删除文件及高级数据恢复等。当用户发生数据丢失问题时&#xff0c;第一时间想到的就是使用数据恢复软件来恢复已经丢失的文件。在众…

【机器学习】集成学习解读(ensemble learning)

【机器学习】集成学习解读&#xff08;ensemble learning&#xff09; 文章目录 【机器学习】集成学习解读&#xff08;ensemble learning&#xff09;1. 集成学习(ensemble learning)1.1 前言1.2 什么是集成学习 2. 如何得到若干个个体学习器2.1 集成学习之 Bagging2.2 集成学…

《Netty》从零开始学netty源码(五十三)之PoolThreadCache的功能

allocateNormal 在前面分析PoolArena的分配内存的方法中&#xff0c;每次分配都是先从本地线程缓存中分配&#xff0c;本地线程缓存PoolThreadCache的分配方法如下&#xff1a; 分配过程主要有两步&#xff1a; 从PoolThreadCache的缓存数组中获取相应大小的缓存cache将需要…

手残也不该敲的命令

Linux命令是一种很有趣且有用的东西&#xff0c;但在你不知道会带来什么后果的时候&#xff0c;它又会显得非常危险。所以&#xff0c;在输入某些命令前&#xff0c;请多多检查再敲回车。 rm –rf rm –rf是删除文件夹和里面附带内容的一种最快捷的方法&#xff0c;但是细微的…

mybatis拦截器统一处理createBy、createTime、updateBy等字段

一、问题描述 createBy 、createTime、updateBy等字段是我们创建表的时候经常要用到的几个字段&#xff0c;但是我们不可能每一次在增删改查的时候都手动去修改或者添加这几个字段的属性值&#xff0c;我们可以在系统层面统一处理&#xff0c;如何实现呢&#xff1f; 二、实现…

轻松掌握KubeKey单节点和集群安装k8s和kubesphere

1、KubeKey单节点AllInOne装kubesphere及k8s 如果只想安装k8s&#xff0c;注意在命令里不指定kubesphere即可。 1、设置hostname hostnamectl set-hostname k8s-node05 2、准备KubeKey export KKZONEcncurl -sfL https://get-kk.kubesphere.io | VERSIONv1.1.1 sh -chmod …

Codeforces Round 867 (Div. 3) AK题解

目录 A. TubeTube Feed&#xff08;签到&#xff09; 题意&#xff1a; 思路&#xff1a; 代码&#xff1a; B. Karina and Array&#xff08;签到&#xff09; 题意&#xff1a; 思路&#xff1a; 代码&#xff1a; C. Bun Lover&#xff08;结论&#xff09; 题意&…

C++类和对象(5)

类和对象 1.流插入和流提取的运算符重载2.const成员3.取地址及const取地址操作符重载 1.流插入和流提取的运算符重载 通过函数重载&#xff0c;可以对流插入运算符和流提取运算符进行运算符重载。<<流插入在ostream中&#xff0c;>>流提取在istream中。 ① 流提取…

SpringCloud全面学习笔记之初窥门径篇

目录 前言Docker初见小鲸鱼Docker架构Docker的安装Docker基操Dockerfile自定义镜像Docker-ComposeDocker镜像仓库 异步通信初识MQ同步通讯异步通讯MQ常见框架 RabbitMQ快速入门RabbitMQ概述和安装常见消息模型快速入门 SpringAMQPBasic Queue 简单队列模型Work Queue 工作队列模…

ChatGPT - 高效编写Prompt

文章目录 概念prompt基本结构如何编写prompt指导组合使用将指令提示、角色提示和种子词提示技术结合使用&#xff1a;将标准提示、角色提示和种子词提示技术结合使用的示例&#xff1a; 资料 概念 prompt 是给预训练语言模型 的一个线索/提示&#xff0c;更好的理解 人类的问题…

深入剖析PyTorch和TensorFlow:理解二者的区别与联系

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

java基础入门-02-【面向对象】

Java基础入门-02-【面向对象】 8、面向对象8.1. 类和对象8.1.1 类和对象的理解8.1.2 类的定义8.1.3 对象的使用8.1.4 学生对象-练习 8.2. 对象内存图8.2.1 单个对象内存图8.2.2 多个对象内存图 8.3. 成员变量和局部变量8.3.1 成员变量和局部变量的区别 8.4. 封装8.4.1 封装思想…

JavaSE基础(四)—— 数组、内存分配

目录 一、数组的定义 1. 静态初始化数组 1.1 数组的访问 1.2 数组的几个注意事项 2. 动态初始化数组 2.1 动态初始化数组的元素默认值 3. 两种初始化的的使用场景总结、注意事项说明 二、数组的遍历 三、数组的案例 1. 数组元素求和 2. 数组求最值 3. 数组…

系统辨识——最小二乘法

基本原理 数学推导 最小二乘法是通过输入数据与输出数据来拟合已知结构的函数关系&#xff0c;也就是说已知二者的函数关系&#xff0c;通过最小二乘法估计函数的相关参数。假设 x , y x,y x,y存在以下函数关系&#xff1a; 但是在实际中&#xff0c;测量数据时存在测量误差或…