描述
合并 k 个升序的链表并将结果作为一个升序的链表返回其头节点。
数据范围:节点总数 0 \le n \le 50000≤n≤5000,每个节点的val满足 |val| <= 1000∣val∣<=1000
要求:时间复杂度 O(nlogn)O(nlogn)
示例1
输入:
[{1,2,3},{4,5,6,7}]
复制返回值:
{1,2,3,4,5,6,7}
示例2
输入:
[{1,2},{1,4,5},{6}]
返回值:
{1,1,2,4,5,6}
方法1:遍历(暴力)
思路:就是把k个链表,遍历一遍,把它们存入到一个数组中,然后对数组进行排序,排完序后,创建链表,将数组内容一对一的存入创建好的链表中,最后返回链表。
代码:
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*
* C语言声明定义全局变量请加上static,防止重复定义
*/
/**
*
* @param lists ListNode类一维数组
* @param listsLen int lists数组长度
* @return ListNode类
*/
/*
struct ListNode* merge(struct ListNode * p,struct ListNode* q){
struct ListNode* cur=malloc(sizeof(struct ListNode)*1);
struct ListNode* t=cur;
while(p!=NULL&&q!=NULL){
if(p->val<q->val){
t->next=p;
p=p->next;
}
else{
t->next=q;
q=q->next;
}
t=t->next;
}
if(p!=NULL||q!=NULL){
t->next=p!=NULL?p:q;
}
return cur->next;
}
*/
struct ListNode* sortListNode(struct ListNode* head){
struct ListNode * p=head,*q=p->next;
int temp;
while(p){
while(q){
if(p->val>q->val){
temp=p->val;
p->val=q->val;
q->val=temp;
}
q=q->next;
}
p=p->next;
q=p->next;
}
return head;
}
struct ListNode* mergeKLists(struct ListNode** lists, int listsLen ) {
// write code here
struct ListNode * pre=malloc(sizeof(struct ListNode)*1); //带头结点
struct ListNode* p=pre; //头结点,存储合并后的所有链表
if(listsLen==0){
return NULL;
}
for(int i=0;i<listsLen;i++){
//遍历链表数组
struct ListNode* t=lists[i];
//遍历每个链表,存入到数组中
while(t){
p->next=t;
p=t; //最后一个节点
t=t->next;
}
}
p=sortListNode(pre->next);
return p;
}
方法2:使用两两归并的方法
代码以及解析:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
import java.util.ArrayList;
public class Solution {
public ListNode merge(ListNode pnode,ListNode rnode){ //合并两个链表
ListNode cur=new ListNode(0);
ListNode t=cur; //作为头结点
while(pnode!=null&&rnode!=null){
if(pnode.val<rnode.val){
t.next=pnode;
pnode=pnode.next;
}
else{
t.next=rnode;
rnode=rnode.next;
}
t=t.next; //新的节点遍历到尾
}
if(pnode!=null||rnode!=null)
t.next=pnode!=null?pnode:rnode;
return cur.next;
}
//k个链表两两合并,最后只有1个链表,这里取数组列表中第l个链表~第r个链表合并
public ListNode mergeList(ArrayList<ListNode> list,int l,int r){
if(l>r){
return null;
}
if(l==r){
return list.get(l); //取第l个链表
}
int mid=l+(r-l)/2;
return merge(mergeList( list,l,mid),mergeList(list,mid+1,r));
}
public ListNode mergeKLists(ArrayList<ListNode> lists) {
ListNode head=mergeList(lists,0,lists.size()-1);
return head;
}
}