LeetCode每日一题Day5——21. 合并两个有序链表

news2024/11/18 0:00:09

博主:命运之光 

🦄专栏:算法修炼之练气篇(C\C++版)

🍓专栏:算法修炼之筑基篇(C\C++版)

🐳专栏:算法修炼之练气篇(Python版)

博主的其他文章:点击进入博主的主页 

前言:欢迎来到这个LeetCode每日算法题专栏!

🌊无论你是编程新手还是有一定经验的开发者,掌握算法和数据结构都是成功的关键。在这个专栏里,我将每天为你分享一道算法题,并提供简单易懂的解析和讲解。

☀️通过每日挑战,你将逐渐培养解决问题的思维方式,掌握重要的编程技巧。无论是面试准备还是日常编码,这些知识都将对你大有裨益。

🎉让我们一起开始这段充满乐趣和成长的学习之旅吧!希望你能从中受益,开拓编程的新视野!

目录

21. 合并两个有序链表

正确答案

方法一:暴力破解

提交记录

详细解析该题代码(方法一:暴力破解)

方法二:递归法解题

提交记录

详细解析该题代码(方法二:递归法解题)

结语


21. 合并两个有序链表

正确答案

方法一:暴力破解

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode dummy=ListNode(-1);
        ListNode *prev=&dummy;
        while(l1 != nullptr && l2 != nullptr){
            if(l1->val < l2->val){
                prev->next=l1;
                l1 = l1->next;
            }
            else{
                prev->next = l2;
                l2 = l2->next;
            }
            prev = prev->next;
        }
        prev->next=l1==nullptr?l2:l1;
        return dummy.next;
    }
};

提交记录

详细解析该题代码(方法一:暴力破解)

这段代码是一个用于合并两个升序链表的C++函数,其中使用了单链表的数据结构。现在,我将逐行解析代码的功能:

  1. 定义了一个单链表的数据结构 ListNode,每个节点包含一个整数值 val 和一个指向下一个节点的指针 next。该数据结构提供了三个构造函数:
    • ListNode():无参构造函数,初始化 val 为0,next 为nullptr。
    • ListNode(int x):带参构造函数,初始化 val 为给定的整数x,next 为nullptr。
    • ListNode(int x, ListNode *next):带参构造函数,初始化 val 为给定的整数x,next 为指向给定节点的指针。
  1. 接下来是一个C++类 Solution 的定义。该类中有一个公共成员函数 mergeTwoLists,它用于合并两个升序链表。该函数接受两个指向链表头节点的指针 l1l2,并返回一个指向合并后链表头节点的指针。
  2. mergeTwoLists 函数中:
    • 创建了一个名为 dummyListNode 对象,并初始化其值为-1。这个 dummy 节点在合并过程中起到了哨兵节点的作用,它不包含实际数据,只是用来简化代码逻辑。
    • 创建一个指向 dummy 节点的指针 prev,用于跟踪合并后链表的末尾节点。
  1. 使用 while 循环进行链表的合并,循环条件是 l1l2 都不为nullptr(即还有节点需要合并)。
    • 在循环体中,比较 l1->vall2->val 的大小,如果 l1 的值小于 l2,则将 l1 添加到合并后链表的末尾,并将 l1 指针移动到下一个节点;否则,将 l2 添加到合并后链表的末尾,并将 l2 指针移动到下一个节点。
    • 然后,将 prev 指针移动到合并后链表的末尾。
  1. 当循环结束后,有可能 l1l2 中还有剩余节点未合并,此时需要将剩余的部分直接添加到合并后链表的末尾。这里使用了三目运算符 l1==nullptr?l2:l1 来确定应该将哪个链表的剩余部分添加到末尾。
  2. 最后,返回 dummy.next,即合并后链表的头节点的指针。由于 dummy 是一个临时节点,实际的合并后链表从 dummy.next 开始。

总体来说,这段代码通过迭代遍历两个升序链表,根据节点值的大小将节点逐个合并,并返回合并后的链表头节点的指针。合并后的链表仍然保持升序。

方法二:递归法解题

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if (l1 == nullptr) {
            return l2;
        }
        if (l2 == nullptr) {
            return l1;
        }
        
        if (l1->val < l2->val) {
            l1->next = mergeTwoLists(l1->next, l2);
            return l1;
        } else {
            l2->next = mergeTwoLists(l1, l2->next);
            return l2;
        }
    }
};

提交记录

详细解析该题代码(方法二:递归法解题)

除了迭代法外,还有递归法可以解决合并两个升序链表的问题。我将为你介绍递归法的解题思路和代码示例。

递归法的思路是基于合并两个升序链表的子问题。假设我们已经知道如何合并两个以 l1l2 为头节点的升序链表,我们可以将问题转化为合并以 l1->nextl2 为头节点的升序链表,并将结果连接到 l1 上。这样,问题规模不断缩小,最终合并两个链表的问题将转化为合并两个小一些的链表的问题,直到其中一个链表为空。

下面是用递归法解决问题的代码示例:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if (l1 == nullptr) {
            return l2;
        }
        if (l2 == nullptr) {
            return l1;
        }
        
        if (l1->val < l2->val) {
            l1->next = mergeTwoLists(l1->next, l2);
            return l1;
        } else {
            l2->next = mergeTwoLists(l1, l2->next);
            return l2;
        }
    }
};

在递归函数 mergeTwoLists 中,我们首先处理边界情况,即如果其中一个链表为空,直接返回另一个链表。然后,我们比较 l1->vall2->val 的大小,如果 l1 的值小于 l2,则将 l1 的下一个节点与合并后的链表连接,并返回 l1;否则,将 l2 的下一个节点与合并后的链表连接,并返回 l2

递归法的思路较为简洁,但需要注意对递归深度的控制,防止出现栈溢出的情况。在实际应用中,可能需要对递归深度进行限制或使用迭代法来处理大规模的链表。

结语

再接再厉,继续加油!


本章的内容就到这里了,觉得对你有帮助的话就支持一下博主把~

🌌点击下方个人名片,交流会更方便哦~
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓

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

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

相关文章

力扣 1049. 最后一块石头的重量 II

题目来源&#xff1a;https://leetcode.cn/problems/last-stone-weight-ii/description/ C题解&#xff08;思路来源代码随想录&#xff09;&#xff1a;本题其实就是尽量让石头分成重量相同的两堆&#xff0c;相撞之后剩下的石头最小&#xff0c;这样就化解成01背包问题了。 …

第一章-JavaScript基础进阶part2:事件

文章目录 概念一、注册事件&#xff08;绑定事件&#xff09;1.1 addEventListener事件监听 二、删除事件&#xff08;解绑&#xff09;三、DOM事件流四、事件对象event4.1 e.target与this与e.currentTarget的区别4.2 事件对象的常见属性 五、阻止事件默认行为及冒泡六、事件委…

【CSS】旋转中的视差效果

效果 index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"/><meta http-equiv"X-UA-Compatible" content"IEedge"/><meta name"viewport" content"widthdevice-…

【SpringBoot】日志是+基于lombok的日志输出

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE进阶 在我们日常的程序开发中&#xff0c;日志是程序的重要组成部分&#xff0c;想象⼀下&#xff0c;如果程序报错了&#xff0c;不让你打开控制台看⽇志&#xff0c;那么你能找到报错的原因吗…

网络安全设备-等保一体机

本文为作者学习文章&#xff0c;按作者习惯写成&#xff0c;如有错误或需要追加内容请留言&#xff08;不喜勿喷&#xff09; 本文为追加文章&#xff0c;后期慢慢追加 等保一体机的功能 等保一体机产品主要依赖于其丰富的安全网元&#xff08;安全网元包括&#xff1a;防火…

problem(3):python IDE和python解释器

为什么写这篇文章呢&#xff1f;遇到了下面的问题&#xff0c;相同的解释器&#xff0c;如果运行angr库的代码&#xff0c;会出现 这样的情况&#xff0c;但是用spyder IDE 会显示正常&#xff0c;很奇怪 应该就是IDE的原因 IDE的循环导入问题 检查IDE配置&#xff1a; 如果可…

DoIP学习笔记系列:(四)用CAPL脚本读取DID的关键点

文章目录 1. 如何在CAPL中读取DID?1.1 避坑如何新建CAPL工程,在此不再赘述,本章主要分享一下如何在CAPL中调用DoIP接口、diag接口进行DoIP和诊断的测试。 1. 如何在CAPL中读取DID? 通常在实际项目中,会有很多DID,各种版本号、各种观测量,如果手动点,显然很麻烦,如果要…

pyspark使用XGboost训练模型实例

遇到一个还不错的使用Xgboost训练模型的githubhttps://github.com/MachineLP/Spark-/tree/master/pyspark-xgboost 1、这是一个跑通的代码实例&#xff0c;使用的是泰坦尼克生还数据&#xff0c;分类模型。 这里使用了Pipeline来封装特征处理和模型训练步骤&#xff0c;保存为…

多语言gRPC开发入门与避坑指南

目录 gRPC相关介绍 什么是gPRC gPRC的优点 gPRC的缺点 gPRC定位 协议缓冲区&#xff08;Protocol Buffers&#xff09; 四种调用方式 gRPC开发三大步骤 第一步&#xff1a;定义和编写proto服务文件 第二步&#xff1a;proto文件转化为gRPC代码 第三步&#xff1a;调…

vue3—SCSS的安装、配置与使用

SCSS 安装 使用npm安装scss&#xff1a; npm install sass sass-loader --save-dev 配置 配置到全局 &#x1f31f;附赠代码&#x1f31f; css: {preprocessorOptions: {scss: {additionalData:import "./src/Function/Easy_I_Function/Echarts/ToSeeEcharts/utill.…

caj文件怎么转换成pdf?了解一下这种方法

caj文件怎么转换成pdf&#xff1f;如果你曾经遇到过需要将CAJ文件转换成PDF格式的情况&#xff0c;那么你一定知道这是一件麻烦的事情。幸运的是&#xff0c;现在有许多软件和工具可以帮助你完成这项任务。下面就给大家介绍一款使用工具。 【迅捷PDF转换器】是一款功能强大的工…

camunda-modeler(5.9.0)介绍及下载

官网地址: https://camunda.com/ 中文站点:http://camunda-cn.shaochenfeng.com Camunda Modeler是一个用于创建、编辑和验证BPMN、CMMN和DMN模型的工具。它提供了一个可视化的界面&#xff0c;使用户可以以图形方式设计和调整工作流程、决策表和案例管理模型。 具体来说&…

8266 ESP-07模块的使用 以及详细介绍

esp8266系列 陶瓷天线 版本 详细介绍说明 最近使用8266的ESP-01S做了个数据无线收发装置&#xff0c;发现板载天线信号太弱&#xff0c;装上外壳后信号更弱&#xff0c;因此考虑能否使用带有外接天线的模块代替ESP-01S。经过在安可信官网搜索发现&#xff0c;ESP07、ESP07S、ES…

2023上半年手机及数码行业分析报告(京东销售数据分析)

2023年上半年&#xff0c;手机市场迎来复苏&#xff0c;同环比来看&#xff0c;销量销额纷纷上涨。 而数码市场中&#xff0c;各个热门品类表现不一。微单相机及智能手表同比去年呈现增长态势&#xff0c;而笔记本电脑市场则出现下滑。 基于此现状&#xff0c;鲸参谋发布了20…

Python实现(条形码,二维码)生成识别

Python实现&#xff08;二维码&#xff0c;条形码&#xff09;生成识别 生成条形码生成二维码识别条形码二维码 生成条形码 安装barcode模块: $ pip install python-barcode barcode文档 import barcode from barcode.writer import ImageWriter # 更多了解&#xff1a;https…

TX验证码

好久没分享文章了&#xff0c;今天来水水文章。 水的意思就是&#xff1a;文章不会分析参数的生成流程。 最开始菜鸡弟弟以为腾讯防水墙就只有一个滑块来着&#xff0c;也感谢不不哥哥提供的网址。 来看下tx旗下的验证类型。 当然除了这些之外&#xff0c;还有一种六宫格的&a…

心率变异性HRV指标说明:SDNN,SDANN,RMSSD,SDNNIndex,SDSD,NN50,PNN50;TP,ULF,VLF,LF,HF

自主神经活动与多种疾病有关系&#xff0c;特别是与某些心血管疾病的死亡率&#xff0c;尤其与猝死率有关。同时&#xff0c;也公认心率变异性&#xff08;HRV&#xff09;分析是判断自主神经活动的常用的定量指标。HRV降低是预测心脏病人死亡的独立危险因子&#xff0c;有十分…

java gc分析

使用工具转换&#xff1a;https://ctbots.com/#/ 通用GC分析 jstat -gc -t pid堆内存分析 jstat -gccapacity -t pid年轻代GC分析 jstat -gcnew -t pid年轻代内存分析 jstat -gcnewcapacity -t pid老年代GC分析 jstat -gcold -t pid老年代内存分析 jstat -gcoldcapacity…

IO进程线程第七天(8.4)信号量,条件变量

在第一题的基础上加上一个需求&#xff1a;要求打印&#xff0c;倒置线程&#xff0c;顺序执行。出现的现象为先打印1234567&#xff0c;后打印7654321&#xff08;不使用flag&#xff09; 创建两个线程&#xff0c;其中一个线程读取文件中的数据&#xff0c;另外一个线程将读…

新手Vite打包工具的使用并解决yarn create vite报错

一、手动创建 1.创建vite-Demo文件夹 2.初始化 yarn init -y 3.安装vite yarn add -D vite 4.打包准备 说明&#xff1a;不需要在src下面创建&#xff0c;在vite-Demo文件夹创建 4.1index.js文件 document.body.insertAdjacentHTML("beforeend","<h1>…