(分治算法2)leecode 23 合并k个升序链表

题目描述

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

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

分治解法

因为是要合并K个有序列表,可以采用归并排序,先把第一个和第二个合并成功,合并完成的再和第三个合并。合并完成的再和第四个合并,合并完成的再和第五个合并。
合并两个有序的链表

private ListNode merge2Lists(ListNode l1,ListNode l2){
	if(l1 == null){
		return l2;
	}
	if(l2 == null){
		return l1;
	}
	if(l1.val < l2.val){
		l1.next = merge2Lists(l1.next,l2);
		return l1;
	}
	l2.next = merge2Lists(l1,l2.next);
	return l2;
}

然后逐一合并两个链表

class Solution{
	public ListNode mergeKLists(ListNode[] lists){
		ListNode res = null;
		for(ListNode list : lists){
			res = merge2List(res,list);
		}
		return res;
	}
}

分治策略

如果我们每次合并的数组尽可能的短,则我们的方法可以在更快地速度合并完所有数组,因此我们将所有的链表均分,然后将均分后的链表继续均分。

class Solution{
	public ListNode MergeKLists(ListNode[] lists){
		return mergeKLists(lists,0,lists,length);
	}
	//合并左半部分和右半部分数组
	private ListNode mergeKLists(lists,int i, int j){
		int m = j-i;
		//说明不需要合并
		if(m == 0) return null;
		if(m == 1) return lists[i];//无需合并直接返回
		ListNode left = mergeKLists(lists, i, i+m/2);
		ListNode right = mergeKLists(lists,i+m/2,j);
		return mergeTwoLists(left,right);//最后把左半部分和右半部分合并即可
	}
	public ListNode mergeTwoLists(ListNode list1,ListNode list2){
		ListNode dummy = new ListNode(); //使用哨兵节点简化代码逻辑
		ListNode cur = dummy;
		while(list1 != null && list2 != null){
			if(list1.val  < list2.val){
				cur.next = list1;// 把list1加到新的链表中
				list1 = list1.next;
			}else {
				cur.next = list2;
				list2 = list2.next;
				
			}
			cur = cur.next;
		}
		cur.next = list1 !=null? list1 : list2;
		return dummy.next;
	}
}

时间复杂度是O(nlogk)的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值