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

相关推荐
鹤上听雷2 分钟前
【AGC005D】~K Perm Counting(计数抽象成图)
算法
睡觉然后上课12 分钟前
c基础面试题
c语言·开发语言·c++·面试
一叶祇秋15 分钟前
Leetcode - 周赛417
算法·leetcode·职场和发展
qing_04060319 分钟前
C++——继承
开发语言·c++·继承
武昌库里写JAVA19 分钟前
【Java】Java面试题笔试
c语言·开发语言·数据结构·算法·二维数组
ya888g20 分钟前
GESP C++四级样题卷
java·c++·算法
小叶学C++36 分钟前
【C++】类与对象(下)
java·开发语言·c++
Funny_AI_LAB1 小时前
MetaAI最新开源Llama3.2亮点及使用指南
算法·计算机视觉·语言模型·llama·facebook
NuyoahC1 小时前
算法笔记(十一)——优先级队列(堆)
c++·笔记·算法·优先级队列
jk_1011 小时前
MATLAB中decomposition函数用法
开发语言·算法·matlab