LeetCode 算法:合并两个有序链表 c++

原题链接🔗合并两个有序链表
难度:简单⭐️

题目

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

示例 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. 题解

合并两个有序链表的问题可以通过多种方法解决,但最常见的方法是使用迭代。以下是解决这个问题的一般思路:

  • 定义节点结构:首先定义链表节点的数据结构,通常包含节点的值和指向下一个节点的指针。

  • 初始化哑节点:创建一个哑节点(dummy node),它将作为合并后链表的前驱节点。使用哑节点的好处是可以直接返回哑节点的下一个节点作为合并后的链表的头节点。

  • 迭代合并:使用两个指针分别指向两个链表的当前节点,比较它们的值,将较小的节点连接到结果链表上,并将该节点的指针向前移动一位。

  • 处理剩余节点:当其中一个链表遍历完成后,将另一个链表剩余的部分直接连接到结果链表的末尾。

  • 返回结果:返回哑节点的下一个节点,即合并后链表的头节点。

  1. 复杂度:时间复杂度O(m+n),其中 n 和 m 分别为两个链表的长度。因为每次循环迭代中,l1 和 l2 只有一个元素会被放进合并链表中, 因此 while 循环的次数不会超过两个链表的长度之和。所有其他操作的时间复杂度都是常数级别的;空间复杂度O(1),只需要常数的空间存放若干变量。

  2. 过程:

  • 创建哑节点:ListNode* dummy = new ListNode(0);
  • 初始化尾指针:ListNode* tail = dummy;
  • 迭代比较:使用一个循环,当两个链表的当前节点都不为空时,进行以下操作:
    • 比较两个链表当前节点的值。
    • 将较小节点连接到tail的后面。
    • 移动tail和较小节点的指针。
  • 连接剩余节点:当其中一个链表的节点为空时,将另一个链表的剩余部分直接连接到tail后面。
  • 返回结果:返回dummy->next作为合并后链表的头节点。
  1. c++ demo
cpp 复制代码
#include <iostream>

struct ListNode {
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(nullptr) {}
};

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        // 创建一个哑节点,作为合并后链表的起始点
        ListNode* dummy = new ListNode(0);
        ListNode* tail = dummy;

        // 用哑节点的 next 指针来逐步构建合并后的链表
        while (l1 != nullptr && l2 != nullptr) {
            if (l1->val < l2->val) {
                tail->next = l1;
                l1 = l1->next;
            }
            else {
                tail->next = l2;
                l2 = l2->next;
            }
            tail = tail->next;
        }

        // 将剩余的非空链表接在合并后的链表后面
        if (l1 != nullptr) {
            tail->next = l1;
        }
        else {
            tail->next = l2;
        }

        // 返回合并后的链表的头节点
        ListNode* result = dummy->next;
        delete dummy; // 释放哑节点
        return result;
    }
};

int main() {
    // 测试代码
    ListNode* l1 = new ListNode(1);
    l1->next = new ListNode(2);
    l1->next->next = new ListNode(4);

    ListNode* l2 = new ListNode(1);
    l2->next = new ListNode(3);
    l2->next->next = new ListNode(4);

    Solution solution;
    ListNode* mergedList = solution.mergeTwoLists(l1, l2);

    // 打印合并后的链表
    while (mergedList != nullptr) {
        std::cout << mergedList->val << " ";
        ListNode* temp = mergedList;
        mergedList = mergedList->next;
        delete temp; // 释放节点
    }
    std::cout << std::endl;

    return 0;
}
  • 输出结果:

1 1 2 3 4 4

相关推荐
JieE21216 小时前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack201 天前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树1 天前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色
JieE2122 天前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法
JieE2122 天前
LeetCode 104. 二叉树的最大深度|递归思路超详细拆解
javascript·算法
vivo互联网技术2 天前
CVPR 2026 | 全新强化学习框架 BeautyGRPO:重塑真实人像
算法·大模型·cvpr·影像
Darling噜啦啦2 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
clint4562 天前
C++进阶(1)——前景提要
c++
用户497863050732 天前
(一)小红的数组操作
算法·编程语言