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

相关推荐
xiaoshiguang33 小时前
LeetCode:222.完全二叉树节点的数量
算法·leetcode
爱吃西瓜的小菜鸡3 小时前
【C语言】判断回文
c语言·学习·算法
别NULL3 小时前
机试题——疯长的草
数据结构·c++·算法
TT哇3 小时前
*【每日一题 提高题】[蓝桥杯 2022 国 A] 选素数
java·算法·蓝桥杯
CYBEREXP20084 小时前
MacOS M3源代码编译Qt6.8.1
c++·qt·macos
ZSYP-S4 小时前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
yuanbenshidiaos5 小时前
c++------------------函数
开发语言·c++
yuanbenshidiaos5 小时前
C++----------函数的调用机制
java·c++·算法
唐叔在学习5 小时前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
ALISHENGYA5 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法