每日打卡:合并K个升序链表

119 阅读1分钟

这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战

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

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

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
  1->4->5,
  1->3->4,
  2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6

原文链接

看到困难就头疼,但是今天就是要挑战一下,因为这道题我看懂了,我好像知道该怎么办

首先,我们从题目开始分析,合并 K个 升序 链表,

那么这道题它属于合并链表,我们之前都应该知道怎么去合并链表

public ListNode mergeList(ListNode a,ListNode b){
         if(a==null||b==null){
            return a!=null ?a:b;
        }
        ListNode head = new ListNode(0);
        ListNode temp = head;
        while(a!=null && b!=null){
            if(a.val<b.val){
                temp.next=a;
                a=a.next;
            }else{
                temp.next=b;
                b=b.next;
            }
            temp=temp.next;
        }
        temp.next=(a!=null?a:b);
        return head.next;
    }

以上就是我们两个链表合并的代码,那我们两个链表都能合并,我们就一直慢慢的去合并就完事了啊,

我们先合并两个,之后用已经合并完的两边去和新的链表合并进行n-1次合并就可以完成我们的题目

我们创建now去维护我们已经合并完的链表把每次新的链表和我们的now去合并

    public ListNode mergeKLists(ListNode[] lists) {
        ListNode now = null;
        for (int i = 0; i < lists.length; ++i) {
            now = mergeList(now, lists[i]);
        }
        return now;
    }

到这里我们的这道题就已经可以算作是完成了,但我们还是要对这个解法进行优化一下,我们已经都是两两合并,我们可以让他每两个进行一次,合并之后在进行我们之前的操作,这样可以减少我们的空间和时间复杂度

    public ListNode mergeKLists(ListNode[] lists) {

        return merge(lists,0,lists.length-1);
    }
    public ListNode merge(ListNode []lists,int left,int right){
        if(left==right){
            return lists[left];
        }
        if(left>right){
            return null;
        }
        int mid =(left+right)>>1;
        return mergeList(merge(lists,left,mid),merge(lists,mid+1,right));
    }

总的来说,这道题虽然是困难等级的,但是也是比较好解决的,我们把复杂的问题,分化成我们能解决的小问题

到最后我们就能解决这个大问题了。