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

LeetCode hot 100—合并两个有序链表

题目

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

示例

示例 1:

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

示例 2:

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

示例 3:

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

分析

迭代法

我们使用一个虚拟头节点(dummy node)。这个节点不存储实际数据,只是为了方便操作,它的 next 指针将指向合并后的链表的头节点。

逐步比较两个链表的当前节点,将较小的节点连接到 tail 后面,并移动相应的链表指针。当一个链表遍历完后,直接将另一个链表的剩余部分连接到新链表的末尾。

时间复杂度:O(n+m), n 和 m 分别为两个链表的长度

空间复杂度:O(1)

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        // 创建一个虚拟头节点
        ListNode dummy;
        ListNode* tail = &dummy;
        // 比较两个链表的节点,按顺序连接到新链表
        while (list1 && list2) {
            if (list1->val < list2->val) {
                tail->next = list1;
                list1 = list1->next;
            } else {
                tail->next = list2;
                list2 = list2->next;
            }
            tail = tail->next;
        }
        // 连接剩余的节点
        if (list1) {
            tail->next = list1;
        } else {
            tail->next = list2;
        }
        // 返回合并后的链表
        return dummy.next;
    }
};

递归法

每次递归调用返回合并后的链表的头节点。通过递归调用栈,逐层返回合并后的链表,最终返回完整的合并链表。

时间复杂度:O(n+m), n 和 m 分别为两个链表的长度

空间复杂度:O(n+m)

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        // 递归终止条件
        if (!list1) return list2;
        if (!list2) return list1;
        // 递归合并
        if (list1->val < list2->val) {
            list1->next = mergeTwoLists(list1->next, list2);
            return list1;
        } else {
            list2->next = mergeTwoLists(list1, list2->next);
            return list2;
        }
    }
};

知识充电

链表

节点定义

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) {}
};

初始化

// 创建链表节点
ListNode* node1 = new ListNode(1);
ListNode* node2 = new ListNode(2);
ListNode* node3 = new ListNode(3);

// 连接节点形成链表: 1 -> 2 -> 3
node1->next = node2;
node2->next = node3;

// node1是链表的头节点
ListNode* head = node1;

遍历链表

void printList(ListNode* head) {
    ListNode* current = head;
    while (current != nullptr) {
        std::cout << current->val << " ";
        current = current->next;
    }
    std::cout << std::endl;
}

插入节点

void insertAtEnd(ListNode*& head, int value) { //在链表的末尾插入一个新节点
    ListNode* newNode = new ListNode(value);
    if (!head) {
        head = newNode;
        return;
    }
    ListNode* current = head;
    while (current->next != nullptr) {
        current = current->next;
    }
    current->next = newNode;
}

删除节点

void deleteNode(ListNode*& head, int value) { //删除链表中第一个值为value的节点
    if (!head) return;
    if (head->val == value) {
        ListNode* temp = head;
        head = head->next;
        delete temp;
        return;
    }
    ListNode* current = head;
    while (current->next && current->next->val != value) {
        current = current->next;
    }
    if (current->next) {
        ListNode* temp = current->next;
        current->next = current->next->next;
        delete temp;
    }
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.dtcms.com/a/48848.html

相关文章:

  • 【Spark+Hive】基于Spark大数据技术小红书舆情分析可视化预测系统(完整系统源码+数据库+开发笔记+详细部署教程+虚拟机分布式启动教程)✅
  • Kotlin函数式编程与Lambda表达式
  • Docker安装Redpandata-console控制台
  • 华硕电脑开启电池保养模式的方法
  • 立体仓WMS同MES制造的协同
  • 2020最新Java面试题
  • opencv 模板匹配方法汇总
  • c语言笔记 数组篇
  • vue videojs使用canvas截取视频画面
  • Linux命令常用的有哪些?
  • nlp第十节——LLM相关
  • 013-2 订单支付超时自动取消订单(rocketmq jpa)
  • 迷你世界脚本玩家接口:Player
  • 蓝桥杯2025模拟三(01字符串)
  • Python Tornado 框架面试题及参考答案
  • 【leetcode hot 100 76】最小覆盖子串
  • TypeScript系列01-类型系统全解析
  • 【中值滤波器(Median Filter)详解】
  • go routine 并发和同步
  • 虚拟机的IP配置
  • 网络安全月度报告
  • LLM 对话框组件 | 字节青训营前端开发项目
  • 计算机网络-实验四子网划分
  • 拒绝被假量薅羊毛,游戏渠道反作弊解决方案发布
  • go类型转换
  • Docker 模拟 kubernetes 的 pod
  • 【C++】:STL详解 —— priority_queue类
  • docker关闭mysql端口映射的使用
  • 计算机基础面试(数据结构)
  • Laravel从入门到精通:开启高效开发之旅