当前位置: 首页 > java >正文

leetcode 21. 合并两个有序链表(c++解法+相关知识点复习)

目录

题目

所需知识点复习

1.链表

1.1单链表

1.2哑结点(Dummy Node)

解答过程

1.循环+双指针解法

2.递归解法


2025.4.29想到其他知识点会后续再继续补充。

题目

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例 1:

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例 2:

输入:l1 = [], l2 = []
输出:[]

示例 3:

输入:l1 = [], l2 = [0]
输出:[0]

提示:

  • 两个链表的节点数目范围是 [0, 50]
  • -100 <= Node.val <= 100
  • l1 和 l2 均按 非递减顺序 排列

所需知识点复习

1.链表

链表(Linked List)是一种线性数据结构,由一系列的节点(Node)组成,每个节点包含:

1.数据域(val):存储数据

2.指针域(next):指向下一个节点

与数组不同,链表的内存不是连续存储的,而是通过指针连接各个节点。

1.1单链表

  • 每个节点包含val和next指针

  • 只能单向遍历(从头到尾)

  • 代码示例
  • struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(nullptr) {}
    };
  • 判断链表是否为空:list1==nullptr

  • 在 C++ 中运算符的使用:

    • 当变量是对象实例时(如 ListNode dummy),使用 . 运算符访问成员(如 dummy.next
    • 当变量是指向对象的指针时(如 ListNode* l1),使用 -> 运算符访问成员(如 l1->val

1.2哑结点(Dummy Node)

哑结点(Dummy Node)是链表操作中常用的技巧,他是一个不存储实际数据的辅助节点,通常作为临时头节点,用于简化链表操作,尤其是在处理边界情况(如空链表、头节点变化等)时非常有用。(常用技巧,可以多加记忆!)

哑结点作用:

  1. 避免空指针异常:当链表可能为空时,使用哑结点可以确保始终有一个初始节点。
  2. 简化插入/删除操作:不需要单独处理头节点的特殊情况,所有操作都可以统一处理。
  3. 方便返回结果:最终返回 dummy.next 即可得到合并后的链表头,无需额外判断。
ListNode dummy(0);  // 创建一个哑结点,值为 0(值不重要)
ListNode* p = &dummy;  // p 是遍历指针,初始指向哑结点
  • dummy 是一个临时头节点,p 用于逐个连接 l1 和 l2 的节点。

  • 最终返回 dummy.next,因为 dummy.next 才是合并后的链表的真正头节点。

解答过程

毫无疑问,我自己没做出来,对链表知识点不熟悉了,紧急复习知识点,并学习了哑结点的使用。

我自己做是,想到了之前两个数组的排序采用的双指针,但是链表是不一样的。

采用循环+双指针的方法进行。方法二就是递归,这个也需要我好好理解一下。

1.循环+双指针解法

/*** 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;ListNode dummy(0);//哑结点用来简化操作ListNode* p=&dummy;//当前节点指针while(l1!=nullptr && l2!=nullptr){if(l1->val>=l2->val){//l1大于l2时,结果指向l2的值p->next=l2;//要移动的应该是指针,而不是直接赋值:eg:p=l2.val是错的。应该创建新节点并连接l2=l2->next;}else{//l1小于l2,结果指向l1的值p->next=l1;l1=l1->next;}p=p->next;}// if(l1!=nullptr){//     p->next=l1;// }// if(l2!=nullptr){//     p->next=l2;// }p->next=(l1!=nullptr)?l1:l2;//替换上面6行代码return dummy.next;}
};

2.递归解法

/*** 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;}l2->next=mergeTwoLists(l1,l2->next);return l2;}
};

http://www.xdnf.cn/news/2889.html

相关文章:

  • 目标检测和目标跟踪的区别与联系
  • 大前端开发——前端知识渐变分层讲解 利用金字塔原理简化前端知识体系
  • 长短期记忆网络(LSTM)
  • MySQL多表操作
  • Ansible 铸就 Linux 安全之盾(Ansible Builds Linux Security Shield)
  • 《软件测试52讲》学习笔记:如何设计一个“好的“测试用例?
  • 【学习资源】知识图谱与大语言模型融合
  • 在Mybatis中写sql的常量应用
  • 万物皆可执行:多功能机器人正在定义新生产力法则
  • Ceph IO读写流程详解(二)——RADOSGW请求处理
  • Lightroom 2025手机版:专业编辑,轻松上手
  • 基于 STM32 的智慧图书馆智能控制系统设计与实现
  • DeepSeek破界而来:重构大规模深度检索的算力与边界
  • Java云原生+quarkus
  • 1.1探索 LLaMA-Factory:大模型微调的一站式解决方案
  • Consul安装部署(Windows环境)
  • 链表反转_leedcodeP206
  • 判断图片url损坏无法展示工具类
  • UE5 Set actor Location和 Set World Location 和 Set Relative Location 的区别
  • 关于本地端口启动问题
  • JAVA--- 关键字static
  • 长效住宅IP是什么?如何获取长效住宅IP?
  • 工程管理部绩效考核关键指标与项目评估
  • 选择排序快速排序
  • 国标GB28181视频平台EasyCVR实用方案:如何实现画面拉伸
  • 大厂Java面试深度解析:Dubbo服务治理、WebSocket实时通信、RESTEasy自定义注解与C3P0连接池配置实践
  • 信创开发中的数据库详解:国产替代背景下的技术生态与实践指南
  • 百度「心响」:通用超级智能体,重新定义AI任务执行新范式
  • Linux CentOS 7 安装Apache 部署html页面
  • 前端 AI 开发实战:基于自定义工具类的大语言模型与语音识别调用指南