23. 合并K个升序链表
这道题,用归并可太秀了。学习一下链表归并的写法(递归,最好也要知道飞递归写法)
关于对链表归并递归解法的理解,这一篇讲得好:
非递归解法就是迭代,穿针引线,改变指针。最好设置一个哨兵节点,操作方便。在“21. 合并两个有序链表”这一题中自己写了一遍,感觉不够优雅,看看别人是怎么写的。
//归并解法,堆解法也要会
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
//特殊边界问什么这样写?包含了输入是[],[[]]的情况吗--不是[[]]长度为1,包含了一个空链表
//lists==null表示数组为空,那lists.length==0是什么?
if(lists==null||lists.length==0) return null;
//只有lists==null时,输入[]报错
//只有lists.length==0时不报错
//最好写if(lists==null||lists.length==0)
return mergeSort(lists,0,lists.length-1);
}
ListNode mergeSort(ListNode[] lists,int left,int right){//[]闭区间
if(left==right)
return lists[left];//有没有必要写left>=right
int mid=left+(right-left)/2;
//mid=left+(right-left)>>1,为什么会报错?
ListNode l1=mergeSort(lists,left,mid);
ListNode l2=mergeSort(lists,mid+1,right);
//有的把分治和归并写到一起
return merge(l1,l2);//把归并后的链返回给上一层,继续归并
//两个链表归并到哪一个位置?--l2--根据merge()的实现分析得知的
}
ListNode merge(ListNode l1,ListNode l2){//函数功能,返回已归并好的链表头
if(l1==null) return l2;//如果l1为空,返回l2,(不管l2是不是空)
if(l2==null) return l1;//l1不为空,返回l1
if(l1.val<l2.val){
l1.next=merge(l1.next,l2);
return l1;
}
else{
l2.next=merge(l1,l2.next);
return l2;
}
}
}

浙公网安备 33010602011771号