【力扣每日一题】23. 合并 K 个升序链表 暴力法-快排 8.12打卡

news2024/11/26 19:42:44

请添加图片描述

文章目录

  • 题目
  • 思路
  • 代码

题目

合并 K 个升序链表

难度: 困难

描述:

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 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

思路

时间复杂度分析:因为允许k的长度为10^4,所以O(n2)是肯定过不去的,可以使用O(nlogn)或者更低,提示中标红处是我们需要注意的地方
解法思路:本题我使用的是暴力解法,首先先将这个链表集合中的所有元素进行合并,生成一个长的链表,因为子链表的长度在500范围内,所以时间复杂度最终会是O(n),同时使用快速排序进行排序,最终时间复杂度在O(nlogn)

代码

先将链表集合中的所有子链表合成一条链表:

 public static ListNode mergeKLists(ListNode[] lists) {
        int k = lists.length;
        ListNode dummy = new ListNode(-1);
        ListNode tail = dummy;
        for(int  i =0;i<k;i++){
            while(lists[i] != null){
                ListNode temp = lists[i];
                lists[i] = lists[i].next;
                tail.next= temp;
                tail = tail.next;
            }
        }
        return quickSort(dummy.next);
    }

然后对链表进行快速排序:
快速排序思路:设置一个中间值,将小于该值的数放在左边,大于的放在右边
针对本题:设置三个链表,一个存储小于的值,一个存储等于的值,一个存储大于的值

public static  ListNode quickSort(ListNode head){
        if(head == null || head.next == null){
            return head;
        }
        ListNode pivot = head;
        ListNode lessHead = new ListNode(-1);
        ListNode lessTail = lessHead;
        ListNode biggerHead = new ListNode(-1);
        ListNode biggerTail = biggerHead;
        ListNode equalHead = new ListNode(-1);
        ListNode equalTail = equalHead;

        ListNode current = head;
        while(current != null){
            if(current.val < pivot.val){
                lessTail.next = current;
                lessTail=lessTail.next;
            }else if(current.val > pivot.val){
                biggerTail.next = current;
                biggerTail = biggerTail.next;
            }else{
                equalTail.next = current;
                equalTail = equalTail.next; 
            }
            current = current.next;
        }
        lessTail.next =null;
        biggerTail.next =null;
        equalTail.next = null;
        
        ListNode sortedLess = quickSort(lessHead.next);
        ListNode sortedBigger = quickSort(biggerHead.next);
        return concer(sortedLess,equalHead.next,sortedBigger);
    }

然后分别从小到大,依此添加到链表中:

 public static ListNode concer(ListNode less,ListNode euqal,ListNode bigger){
        ListNode dummyhead = new ListNode(-1);
        ListNode tail = dummyhead;

        tail.next = less;
        tail = getTail(tail);
        tail.next =euqal ;
        tail = getTail(tail);
        tail.next = bigger;
    

        return dummyhead.next;
    }
    public static ListNode getTail(ListNode head){
        if(head == null){
            return null;
        }
        while(head.next != null){
            head = head.next;
        }
        return head;
    }

我这里使用了最简单的方法,还有很多优质的解法,可以参考力扣中大神的做法。

完整代码:

/**
 * 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 {
    //暴力解法
    public static ListNode mergeKLists(ListNode[] lists) {
        int k = lists.length;
        ListNode dummy = new ListNode(-1);
        ListNode tail = dummy;
        for(int  i =0;i<k;i++){
            while(lists[i] != null){
                ListNode temp = lists[i];
                lists[i] = lists[i].next;
                tail.next= temp;
                tail = tail.next;
            }
        }
        return quickSort(dummy.next);
    }
    public static  ListNode quickSort(ListNode head){
        if(head == null || head.next == null){
            return head;
        }
        ListNode pivot = head;
        ListNode lessHead = new ListNode(-1);
        ListNode lessTail = lessHead;
        ListNode biggerHead = new ListNode(-1);
        ListNode biggerTail = biggerHead;
        ListNode equalHead = new ListNode(-1);
        ListNode equalTail = equalHead;

        ListNode current = head;
        while(current != null){
            if(current.val < pivot.val){
                lessTail.next = current;
                lessTail=lessTail.next;
            }else if(current.val > pivot.val){
                biggerTail.next = current;
                biggerTail = biggerTail.next;
            }else{
                equalTail.next = current;
                equalTail = equalTail.next; 
            }
            current = current.next;
        }
        lessTail.next =null;
        biggerTail.next =null;
        equalTail.next = null;
        
        ListNode sortedLess = quickSort(lessHead.next);
        ListNode sortedBigger = quickSort(biggerHead.next);
        return concer(sortedLess,equalHead.next,sortedBigger);
    }
    public static ListNode concer(ListNode less,ListNode euqal,ListNode bigger){
        ListNode dummyhead = new ListNode(-1);
        ListNode tail = dummyhead;

        tail.next = less;
        tail = getTail(tail);
        tail.next =euqal ;
        tail = getTail(tail);
        tail.next = bigger;
    

        return dummyhead.next;
    }
    public static ListNode getTail(ListNode head){
        if(head == null){
            return null;
        }
        while(head.next != null){
            head = head.next;
        }
        return head;
    }
}

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

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

相关文章

Qt6之QStackedWidget——Qt仿ToDesk(2)

一、 QStackedWidget概述 QStackedWidget也叫堆栈窗体类&#xff0c;它继承于QFrame&#xff0c;主要与QListWidget等结合使用&#xff0c;实现“一个界面多个页面切换”。 二、QStackedWidget示例 如下图&#xff0c;当点击左边 QListWidget里的菜单时&#xff0c;右边跟随切…

深入浅出流批一体理论篇——数据架构的演进

一、前大数据时代 人人都知道罗马不是一天建成的&#xff0c;但没人告诉过你罗马是怎样一天天建成的。你看见罗马时&#xff0c;它就已经是罗马了。当我进阿里时&#xff0c;正是这样的感觉。我没有经历过阿里数据架构&#xff08;包括平台工具&#xff09;从0到1的过程。我相…

计算机科学的伟大变革:从机械计算到人工智能

摘要 计算机科学作为一门学科&#xff0c;经历了几十年的发展和演变。本论文旨在探讨计算机科学领域的伟大变革&#xff0c;从最早的机械计算设备到如今的人工智能系统。通过回顾历史、分析技术进步以及展望未来&#xff0c;我们可以清晰地看到计算机科学如何塑造了现代社会&a…

Flink学习记录

可以快速搭建一个Flink编写程序 mvn archetype:generate \-DarchetypeGroupIdorg.apache.flink \-DarchetypeArtifactIdflink-quickstart-java \-DarchetypeVersion1.17.1 \-DgroupIdcom.zxx.langhuan \-DartifactIdlanghuan-flink \-Dversion1.0.0-SNAPSHOT \-Dpackagecom.zx…

SpringBoot复习:(33)WebMvcAutoconfiguration内部静态类WebMvcAutoConfigurationAdapter

WebMvcAutoconfiguration内部静态类WebMvcAutoConfigurationAdapter实现了WebMvcConfigurer接口&#xff0c;重写了一些方法&#xff0c;也就是默认对Spring Mvc进行了一些配置: 该静态类上有个**Import**注解&#xff1a; Import(EnableWebMvcConfiguration.class) 它的父类…

前端笔试题1

HTML/CSS 题1&#xff1a; 1&#xff0e;使用CSS 让该节点不可见&#xff0c;方法越多越好。 <div class"hidden">Hi</div> 使用CSS 让节点不可见的方法有以下几种&#xff1a; 把 visibility 属性设置为 hidden&#xff0c;这样元素框不会被绘制&…

伯俊ERP对接打通金蝶云星空表头表体组合查询接口与采购订单新增接口

伯俊ERP对接打通金蝶云星空表头表体组合查询接口与采购订单新增接口 数据源平台:伯俊ERP 伯俊科技&#xff0c;依托在企业信息化建设方面的领先技术与实践积累&#xff0c;致力于帮助企业实现全渠道一盘货。伯俊提供数字经营的咨询与系统实施&#xff0c;助力企业信息化升级、加…

【C++】STL初识

1.STL的基本概念 2.vector存放内置数据类型 #include <iostream> using namespace std; #include <vector> #include <algorithm>void MyPrint(int val) {cout << val << endl; }void test01() {//创建vector容器对象&#xff0c;并且通过模板参…

DP1.4接口的PCB布局布线要求

DP接口即为DisplayPort接口&#xff0c;是由视频电子标准协会发布的显示接口。DP接口将在传输视频信号的同时加入对高清音频信号传输的支持&#xff0c;并且同时支持更高的分辨率以及刷新率。DP1.4通信端口规范新标准基于DP1.3规范&#xff0c;宽度不变但加入了显示压缩流技术&…

Spring-Cloud-Loadblancer详细分析_3

前两篇文章介绍了加载过程&#xff0c;本文从Feign的入口开始分析执行过程&#xff0c;还是从FeignBlockingLoadBalancerClient.execute来入手 public class FeignBlockingLoadBalancerClient implements Client {private static final Log LOG LogFactory.getLog(FeignBlock…

【TypeScript】进阶之路语法细节,类型和函数

进阶之路 类型别名(type)的使用接口(interface)的声明的使用二者区别&#xff1a; 联合类型和交叉类型联合类型交叉类型 类型断言获取DOM元素 非空类型断言字面量类型的使用类型缩小&#xff08;类型收窄&#xff09;TypeScript 函数类型函数类型表达式内部规则检测函数的调用签…

什么是响应式设计?列举几种实现响应式设计的方法。

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 什么是响应式设计&#xff1f;⭐ 实现响应式设计的方法⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏…

Linux:Shell编程之免交互

目录 绪论 1、here Document免交互 1.1 格式 1.2 cat结合免交互实现重定向输出到指定文件 1.3 变量替换 2、Expect免交互 2.1 三种写法 3、免交互实现普通用户切换root 3.1 send_user 4、接收参数 5、嵌入执行模式 6、ssh远程登录 绪论 免交互&#xff1a;不需要人…

【Linux进行时】进程概念

进程的概念 什么是进程呢&#xff1f; ❓首先我们需要认识一下什么叫进程呢&#xff1f; 课本概念&#xff1a;程序的一个执行实例&#xff0c;正在执行的程序等 &#x1f525;内核观点&#xff1a;担当分配系统资源&#xff08;CPU时间&#xff0c;内存&#xff09;的实体。…

海外ASO优化之关于应用的营销2

在目标受众中建立信任度&#xff0c;并获得博客/新闻网站的热榜&#xff0c;这样自然会提高应用的知名度和目标受众的认知度。就博客读者而言&#xff0c;需要找出推荐的最佳时间和真正推动我们应用是什么。 1、提供了App Store或Google Play的直接链接。 我们首先需要创建一个…

2023年中国锂电池X-Ray及CT检测设备市场竞争格局及行业市场规模前景分析[图]

锂电池X-Ray成像检测设备主要是利用X射线穿透电芯时的吸收、反射、散射效应实现成像并对图像进行处理及算法分析&#xff0c;实现非接触式的无损、自动测量锂电池电芯内部特征尺寸以进行瑕疵检测&#xff0c;确认电芯结构是否合格、避免造成电芯内部短路等安全隐患。 锂电池X-…

fork创建多个子进程

fork创建多个子进程 示例代码 fork1.c #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h>int main(int argc,char **argv) {int i, j;pid_t pid;for (i 0; i < 3; i){pid fork();if (pid < 0){perror(&q…

Zip压缩包有密码,如何删除?

Zip压缩包设置设置了密码&#xff0c;想要删除密码&#xff0c;除了将压缩包解压出来之后再将文件压缩为不带密码的压缩文件以外&#xff0c;还有一种删除密码的方法。设置方法如下&#xff1a; 右键点击zip文件&#xff0c;找到打开方式&#xff0c;以Windows资源管理器方式打…

sql server profiler使用

一、打开sql server profiler 二、配置 比如我们只过滤包含这个关键字的&#xff0c;输入&#xff1a;%Employees%