leetcode23 多个拍好序的链表进行归并排序 (java版本)

题目:

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity

思路1:

依次归并排序,首先归并前两个,然后归并完成的链表依次和剩下的链表进行归并排序

时间复杂度为O(m*n)

代码:

public static ListNode mergeKLists1(ListNode[] lists){
int len = lists.length;
if(len == 0){
return null;
}else{
if(len == 1){
return lists[0];
}else{
ListNode headl = new ListNode(-1);
ListNode head1 = lists[0], head2 = lists[1];
for(int i=0; i < len-1; i++){
if(head1 == null){
headl.next = head2;
}else{
if(head2 == null){
headl.next = head1;
}else{
//测量head1的链表长度
int len1 = 0;
ListNode ptr = head1;
while(ptr != null){
len1++;
ptr = ptr.next;
}

//测量head2的长度
int len2 = 0;
ptr = head2;
while(ptr != null){
len2++;
ptr = ptr.next;
}

ptr = headl;
ListNode ptr1 = head1, ptr2 = head2;
for(int j=0; j< len1+len2; j++){
if(ptr1 !=null && ptr2 != null){
if(ptr1.val <= ptr2.val){
ptr.next = ptr1;
ptr1 = ptr1.next;
ptr = ptr.next;
}else{
ptr.next = ptr2;
ptr2 = ptr2.next;
ptr = ptr.next;
}
}else{
if(ptr1 == null){
ptr.next = ptr2;
ptr2 = ptr2.next;
ptr = ptr.next;
}else{
ptr.next = ptr1;
ptr1 = ptr1.next;
ptr = ptr.next;
}
}
}
head1 = headl.next;
if(i+2 <= len-1){
head2 = lists[i+2];
}else{
break;
}
}//else(head1!=null && head2 != null)
}
} //for(int i=0; i < len-1; i++)
return headl.next;
}
}
}

思路2:

分治法

两两归并,递归调用即可。

因为每个链表都已经排序完成了,因此可以把链表数组看成一个待归并排序的数组,对之采用归并排序即可。

时间复杂度为O(n)

AC通过

代码:

public static ListNode mergeKLists(ListNode[] lists){
return mergeKLists(lists, 0, lists.length-1);
}

//分治法果然有效
public static ListNode mergeKLists(ListNode[] lists, int start, int end){
if(start == end){
return lists[start];
}
if(start > end){
return null;
}
int mid = (start + end)/2;
ListNode head1 = mergeKLists(lists, start, mid);
ListNode head2 = mergeKLists(lists, mid+1, end);
ListNode headl = new ListNode(-1);
ListNode ptr = headl;
while(head1 != null && head2 != null){
if(head1.val <= head2.val){
ptr.next = head1;
head1 = head1.next;
ptr = ptr.next;
}else{
ptr.next = head2;
head2 = head2.next;
ptr = ptr.next;
}
}

while(head1 != null){
ptr.next = head1;
head1 = head1.next;
ptr = ptr.next;
}

while(head2 != null){
ptr.next = head2;
head2 = head2.next;
ptr = ptr.next;
}

return headl.next;
}

时间: 2024-10-31 03:12:22

leetcode23 多个拍好序的链表进行归并排序 (java版本)的相关文章

逆序单链表

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

逆序建立链表

题目描述 输入整数个数N,再输入N个整数,按照这些整数输入的相反顺序建立单链表,并依次遍历输出单链表的数据. 输入 第一行输入整数N;: 第二行依次输入N个整数,逆序建立单链表. 输出 依次输出单链表所存放的数据. 示例输入 10 11 3 5 27 9 12 43 16 84 22 示例输出 22 84 16 43 12 9 27 5 3 11 #include <iostream> #include <malloc.h> using namespace std; struct

剑指Offer03 逆序输出链表

多写了个逆序链表 1 /************************************************************************* 2 > File Name: 03_Pirnt_LinkList.c 3 > Author: Juntaran 4 > Mail: [email protected] 5 > Created Time: 2016年08月24日 星期三 02时04分25秒 6 ***************************

合并两个已序单链表

// 合并两个已序单链表 PSListNode MergeList(PSListNode pL1, PSListNode pL2) { PSListNode pNewHead = NULL ; PSListNode pL1Node = pL1 ; PSListNode pL2N0de = pL2 ; PSListNode pNode = NULL ; PSListNode pTailNode = NULL ; if (pL1 == NULL) { return pL2 ; } if (pL2 =

数据结构之 线性表 逆序简历链表

数据结构实验之链表二:逆序建立链表 Time Limit: 1000MS Memory limit: 65536K 题目描述 输入整数个数N,再输入N个整数,按照这些整数输入的相反顺序建立单链表,并依次遍历输出单链表的数据. 输入 第一行输入整数N;: 第二行依次输入N个整数,逆序建立单链表. 输出 依次输出单链表所存放的数据. 示例输入 10 11 3 5 27 9 12 43 16 84 22 示例输出 22 84 16 43 12 9 27 5 3 11 比顺序创建链表还要简单! #inc

面试:用 Java 逆序打印链表

昨天的 Java 实现单例模式 中,我们的双重检验锁机制因为指令重排序问题而引入了 volatile 关键字,不少朋友问我,到底为啥要加 volatile 这个关键字呀,而它,到底又有什么神奇的作用呢? 对 volatile 这个关键字,在昨天的讲解中我们简单说了一下:被 volatile 修饰的共享变量,都会具有下面两个属性: 保证不同线程对该变量操作的内存可见性. 禁止指令重排序. 共享变量:如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量. 可见性:一个线

数据结构实验之链表二:逆序建立链表

数据结构实验之链表二:逆序建立链表 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 输入整数个数N,再输入N个整数,按照这些整数输入的相反顺序建立单链表,并依次遍历输出单链表的数据. Input 第一行输入整数N;:第二行依次输入N个整数,逆序建立单链表. Output 依次输出单链表所存放的数据. Sample Input 10 11 3 5 27 9 12 43 16 84 22 Sample Output 22

C++:探究纯虚析构函数以及实现数组的快速排序与链表的归并排序

C++:探究纯虚析构函数以及实现数组的快速排序与链表的归并排序 by 小威威 1.介绍 本篇博文将通过课后作业的(15 C++ Homework) D&A 5 Collection with Inheritance来讲解一些重要的排序与零散的知识.而且,本人以科学严谨的态度,对抽象类中析构函数的调用情况进行了分类讨论并一一试验,最终得出了"抽象类最好要定义纯虚析构函数"的结论,并不是凭空捏造,或者是从网上拷贝而来.但是,这仍然代表本人观点,不具有权威性,如有错误,欢迎大家批评指

链表的排序----链表的归并排序

链表的归并排序(LinkList merge sort) 首先来看看如果有两条已序(sorted)的链表 ListNode *A ,  和ListNode *B, 如何合并成一条已序的链表呢? ListNode * mergeTwoLists(ListNode *l1, ListNode *l2) { ListNode *head = new ListNode(-1); ListNode *p = head; for(;l1&&l2; p = p->next) { if(l1->