【LeetCode每日一题】——LCR 078.合并 K 个升序链表

news2024/11/18 3:42:03

文章目录

  • 一【题目类别】
  • 二【题目难度】
  • 三【题目编号】
  • 四【题目描述】
  • 五【题目注意】
  • 六【题目示例】
  • 七【题目提示】
  • 八【解题思路】
  • 九【时间频度】
  • 十【代码实现】
  • 十一【提交结果】

一【题目类别】

  • 优先队列

二【题目难度】

  • 困难

三【题目编号】

  • LCR 078.合并 K 个升序链表

四【题目描述】

  • 给定一个链表数组,每个链表都已经按升序排列。
  • 请将所有链表合并到一个升序链表中,返回合并后的链表。

五【题目注意】

  • 本题与主站 23 题相同: https://leetcode-cn.com/problems/merge-k-sorted-lists/

六【题目示例】

  • 示例 1

    • 输入:lists = [[1,4,5],[1,3,4],[2,6]]
    • 输出:[1,1,2,3,4,4,5,6]
    • 解释:链表数组如下:
      [
      1->4->5,
      1->3->4,
      2->6
      ]
      将它们合并到一个有序链表中得到。
      1->1->2->3->4->4->5->6
  • 示例 2

    • 输入:lists = []
    • 输出:[]
  • 示例 3

    • 输入:lists = [[]]
    • 输出:[]

七【题目提示】

  • k == lists.length
  • 0 <= k <= 10^4
  • 0 <= lists[i].length <= 500
  • -10^4 <= lists[i][j] <= 10^4
  • lists[i] 按 升序 排列
  • lists[i].length 的总和不超过 10^4

八【解题思路】

  • 使用优先队列(小顶堆)解决该问题
  • 小顶堆维护各个链表没有被合并的的节点的最前面的节点
  • 这样我们每次都会取出所有链表中值最小的节点
  • 然后依次将所有节点存入小顶堆中再将其合并为一个链表
  • 最后返回结果即可

九【时间频度】

  • 时间复杂度: O ( k n × l o g k ) O(kn × logk) O(kn×logk) k k k为优先队列中的元素个数, n n n为传入的链表个数
  • 空间复杂度: O ( k ) O(k) O(k) k k k为优先队列中的元素个数

十【代码实现】

  1. Java语言版
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {

    // 定义一个类 Status,用来存储链表节点值和对应的节点指针
    class Status implements Comparable<Status> {
        int val;
        ListNode node;

        // 构造函数,初始化节点值和指针
        Status(int val, ListNode node) {
            this.val = val;
            this.node = node;
        }

        // 实现 Comparable 接口,按照节点值从小到大排序
        public int compareTo(Status status) {
            return this.val - status.val;
        }
    }

    // 合并多个有序链表
    public ListNode mergeKLists(ListNode[] lists) {
        // 定义一个优先队列(小顶堆),会根据 Status 类中的节点值进行排序
        PriorityQueue<Status> pQueue = new PriorityQueue<Status>();

        // 遍历所有链表,把每个链表的第一个节点放入优先队列
        for (ListNode node : lists) {
            if (node != null) {
                pQueue.offer(new Status(node.val, node));
            }
        }

        // 创建一个虚拟头节点和尾节点,方便构建结果链表
        ListNode head = new ListNode(0);
        ListNode tail = head;

        // 循环处理优先队列中的节点,直到队列为空
        while (!pQueue.isEmpty()) {
            Status min_node = pQueue.poll();
            tail.next = min_node.node;
            tail = tail.next;
            if (min_node.node.next != null) {
                pQueue.offer(new Status(min_node.node.next.val, min_node.node.next));
            }
        }
        // 返回合并后的链表(哑节点的下一个节点)
        return head.next;
    }
}
  1. Python语言版
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next

import heapq

class Solution:

    # 定义一个类 Status,用来存储链表节点值和对应的节点指针
    class Status:

        # 构造函数,初始化节点值和指针
        def __init__(self, val, node):
            self.val = val
            self.node = node

        # 实现接口,按照节点值从小到大排序
        def __lt__(self, other):
            return self.val < other.val

    # 合并多个有序链表
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        # 定义一个优先队列(小顶堆),会根据 Status 类中的节点值进行排序
        pQueue = []

        # 遍历所有链表,把每个链表的第一个节点放入优先队列
        for node in lists:
            if node is not None:
                heapq.heappush(pQueue, self.Status(node.val, node))
        
        # 创建一个虚拟头节点和尾节点,方便构建结果链表
        head = ListNode(0)
        tail = head

        # 循环处理优先队列中的节点,直到队列为空
        while pQueue:
            min_node = heapq.heappop(pQueue)
            tail.next = min_node.node
            tail = tail.next
            if min_node.node.next is not None:
                heapq.heappush(pQueue, self.Status(min_node.node.next.val, min_node.node.next))
        
        # 返回合并后的链表(哑节点的下一个节点)
        return head.next
  1. C++语言版
/**
 * 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 Status {
    public:
        int val;
        ListNode* node;

        Status(int v, ListNode* n) : val(v), node(n) {}

        bool operator<(const Status& other) const {
            return val > other.val;
        }
};

class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        std::priority_queue<Status> pQueue;

        for (ListNode* node : lists) {
            if (node != nullptr) {
                pQueue.push(Status(node->val, node));
            }
        }

        ListNode* head = new ListNode(0);
        ListNode* tail = head;

        while (!pQueue.empty()) {
            Status min_node = pQueue.top();
            pQueue.pop();
            tail->next = min_node.node;
            tail = tail->next;
            if (min_node.node->next != nullptr) {
                pQueue.push(Status(min_node.node->next->val, min_node.node->next));
            }
        }

        ListNode* result = head->next;
        delete head;
        return result;
    }
};

十一【提交结果】

  1. Java语言版
    在这里插入图片描述

  2. Python语言版
    在这里插入图片描述

  3. C++语言版
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2136668.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux入门——“Linux基本指令”上

在刚开始学习Linux时&#xff0c;首先需要掌握一些基本指令&#xff0c;以便我们能更好地使用Linux操作系统&#xff0c;以下指令在Ubuntu 22上执行。以下内容不过多介绍选项内容。 1.ls指令 ls指令用来查看当前目录下的文件&#xff0c;显示的信息是很有限的一般只显示文件名&…

二进制部署ETCD单机版

文章目录 一、签发etcd证书二、搭建etcd单机版三、测试ETCD服务 一、签发etcd证书 注意&#xff1a;在操作签发证书操作时一定要检查服务器时间、时区是否一致&#xff0c;会导致证书不可用&#xff01;&#xff01; 1、创建etcd目录 mkdir /etc/etcd/{ssl,data} -p2、安装签…

【vue-media-upload】一个好用的上传图片的组件,注意事项

一、问题 media 的saved 数组中的图片使用的是location 相对路径&#xff0c;但是我的业务需要直接根据图片链接展示图片&#xff0c;而且用的也不是location 相关源代码 <div v-for"(image, index) in savedMedia" :key"index" class"mu-image-…

基于SpringBoot的社区宠物管理与推荐系统的设计与实现

文未可获取一份本项目的java源码和数据库参考。 1.课题的基本内容&#xff0c;可能遇到的困难&#xff0c;提出解决问题的方法和措施 2.1课题的基本内容 本课题主要研究基于SpringBoot的社区宠物管理与推荐系统的设计与实现。用户注册登录系统前端后可以可以实现对宠物信息的…

【读书笔记-《30天自制操作系统》-20】Day21

本篇的内容主要是操作系统的保护&#xff0c;涉及到x86 CPU的一些机制&#xff0c;以及操作系统的异常处理。 1. 字符显示API问题解决 首先来解决一下上一篇内容中字符串显示API没有生效的问题。 void hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ec…

为什么H.266未能普及?EasyCVR视频编码技术如何填补市场空白

H.266&#xff0c;也被称为Versatile Video Coding&#xff08;VVC&#xff09;&#xff0c;是近年来由MPEG&#xff08;Moving Picture Experts Group&#xff09;和ITU&#xff08;International Telecommunication Union&#xff09;联合开发并发布的新一代国际视频编码标准…

[每周一更]-(第114期):介绍GitLab不同角色对应的权限

文章目录 GitLab 角色及其权限项目级别角色组级别角色 使用场景示例 工作中一直使用Gitlab搭建了公司内网的代码管理工具&#xff0c;但是不同的用户会分配相应的权限&#xff0c;来管理不同用户及角色的权限信息&#xff0c;我们来介绍下角色的信息&#xff0c;方便我们管理公…

演示:基于WPF的自绘的中国地铁轨道控件

一、目的&#xff1a;演示一个基于WPF的自绘的中国地铁轨道控件 二、效果演示 北京地铁 成都地铁 上海地铁 深圳地铁 南京地铁 长春地铁 哈尔滨地铁 武汉地铁 厦门地铁 香港地铁 三、功能 支持平移、缩放等操作 鼠标悬停显示线路信息和站点信息 按表格显示&#xff0c;按纸张…

传知代码-融合经典与创新的图像分类新途径

代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 概述 在当前的深度学习领域&#xff0c;构建兼具高性能与灵活性的卷积神经网络&#xff08;CNN&#xff09;已成为计算机视觉研究的核心课题。本文介绍了一种全新的卷积神经网络架构&#xff0c;该网络巧妙地结合…

MacOS Sonoma(14.x) 大写模式或中文输入法下的英文模式,光标下方永远会出现的CapsLock箭头Icon的去除办法

如图&#xff0c;MacOS Sonoma(14.x) 大写模式或中文输入法下的英文模式下&#xff0c;光标下方永远会出现一个CapsLock箭头Icon。此Icon挡住视野&#xff0c;还容易误触导致切换大小写状态&#xff0c;带来的收益远远小于带来的困扰。 解决办法 打开终端&#xff0c;输入以下…

Go协程及并发锁应用指南

概念 协程&#xff08;Goroutine&#xff09;是Go语言独有的并发体&#xff0c;是一种轻量级的线程&#xff0c;也被称为用户态线程。相对于传统的多线程编程&#xff0c;协程的优点在于更加轻量级&#xff0c;占用系统资源更少&#xff0c;切换上下文的速度更快&#xff0c;不…

Vue:使用v-model绑定的textarea在光标处插入指定文本

一、问题描述 使用v-model绑定的textarea如果需要改变其内容&#xff0c;一般只要改变v-model对应的变量即可&#xff0c;但如果需要在textarea的当前光标位置插入指定文本&#xff0c;那就需要操作DOM了。于是我们写了一段js&#xff1a; const insertTextAtCursor (text) …

聊天组件 Vue3-beautiful-chat

前言 最近很多公司都在搞大模型&#xff0c;类似于 chatgpt 的功能&#xff1b;而 chatgpt 的界面其实就是个对话框。今天就介绍一个不错的对话框组件 Vue3-beautiful-chat 项目框架 vite vue3 TS Vue3-beautiful-chat 使用流程 1、引用三方件 npm install Vue3-beaut…

【大模型专栏—进阶篇】语言模型创新大总结——“三派纷争”

大模型专栏介绍 &#x1f60a;你好&#xff0c;我是小航&#xff0c;一个正在变秃、变强的文艺倾年。 &#x1f514;本文为大模型专栏子篇&#xff0c;大模型专栏将持续更新&#xff0c;主要讲解大模型从入门到实战打怪升级。如有兴趣&#xff0c;欢迎您的阅读。 &#x1f4…

ChatGPT对话训练数据采集渠道有哪些

ChatGPT是人工智能技术驱动的自然语言处理工具&#xff0c;它可以生成逼真的自然语言回复&#xff0c;被广泛应用于聊天机器人、智能助理等领域。ChatGPT本身需要依赖大量的训练对话数据和算法运行&#xff0c;其所依赖的对话数据&#xff0c;需要专业的数据采集标注处理流程才…

20 递归算法精髓解析:基准、性质、案例(阶乘、斐波拉契、猴子吃桃、汉诺塔等)、与循环的对比

目录 1 概述 2 递归的基本组成部分 2.1 基准情况 2.2 递归步骤 2.3 案例&#xff1a;循环实现阶乘的计算 2.4 案例&#xff1a;递归函数实现阶乘的计算 3 递归的性质 3.1 自我调用 3.2 栈的使用 3.3 问题分解 3.4 性能考虑 3.5 案例&#xff1a;递归的回溯 4 综合…

WPF DataGrid 列表中,DataGrid.Columns 列根据不同的值显示不同内容

需求&#xff1a;在WPF DataGrid 控件中&#xff0c;有以下列&#xff0c;绑定了一个LogType&#xff0c;值分别是0,1,2&#xff0c;根据不同的值&#xff0c;显示不同的内容以及背景 <DataGrid ItemsSource"{Binding EventLog}"><DataGrid.Columns><…

力扣之1777.每家商店的产品价格

文章目录 1. 1777.每家商店的产品价格1.1 题干1.2 建表1.3 题解1.4 结果截图 1. 1777.每家商店的产品价格 1.1 题干 表&#xff1a;Products -------------------- | Column Name | Type | -------------------- | product_id | int | | store | enum | | price | int | ---…

猜数-while-python

题目要求&#xff1a; 设置一个范围1-100的随机整数变量&#xff0c;通过while循环&#xff0c;诶和input语句&#xff0c;判断输入的数字是否等于随机数 无限次机会&#xff0c;直到猜中为止每一次不猜中都&#xff0c;会提示大了小了猜完数字后&#xff0c;提示裁了几次 imp…

K8s 之Pod的定义及详细资源调用案例

资源管理介绍 在kubernetes中&#xff0c;所有的内容都抽象为资源&#xff0c;用户需要通过操作资源来管理kubernetes。kubernetes的本质上就是一个集群系统&#xff0c;用户可以在集群中部署各种服务所谓的部署服务&#xff0c;其实就是在kubernetes集群中运行一个个的容器&a…