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;
        }

    }
}
posted @ 2021-03-29 14:33  wsshub  阅读(48)  评论(0)    收藏  举报