leetcode 23. 合并K个排序链表【堆】

方法1:优先队列

利用java自带的优先队列,通过自定义Comparator实现最小堆,然后将ListNode数组中各个链表的头结点放入优先队列中。优先队列的首个元素即为返回结果的头结点。
然后对队列进行遍历,每取出一个节点后,判断其是否指向下一个节点,若是,则将其下一节点添加入队列,直到整个优先队列为空。

class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists.length==0){
            return null;
        }
        ListNode dummyHead = new ListNode(-1);
        ListNode curr = dummyHead;
        
        Queue<ListNode> q = new PriorityQueue<>(new Comparator<ListNode>(){
            @Override
            public int compare(ListNode node1, ListNode node2){
                return node1.val - node2.val;
            }
        });
        //将全部头结点放入优先队列
        for(ListNode node : lists){
            //头结点可能为null
            if(node == null)continue;
            q.offer(node);
        }
        while(!q.isEmpty()){
            ListNode next = q.poll();
            curr.next = next;
            curr = curr.next;
            if(next.next != null){
                q.offer(next.next);
            }
        }
        return dummyHead.next;
    }
}

方法2:分治法

对k个链表进行合并,可以视为对2个链表进行合并,一共进行k-1次合并操作。

class Solution {
   public ListNode mergeKLists(ListNode[] lists) {
        if (lists == null || lists.length == 0) return null;
        return merge(lists, 0, lists.length - 1);
    }

    private ListNode merge(ListNode[] lists, int left, int right) {
        if (left == right) return lists[left];
        int mid = left + (right - left) / 2;
        ListNode l1 = merge(lists, left, mid);
        ListNode l2 = merge(lists, mid + 1, right);
        return mergeTwoLists(l1, l2);
    }

    private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null) return l2;
        if (l2 == null) return l1;
        if (l1.val < l2.val) {
            l1.next = mergeTwoLists(l1.next, l2);
            return l1;
        } else {
            l2.next = mergeTwoLists(l1,l2.next);
            return l2;
        }
    }
}
发布了55 篇原创文章 · 获赞 0 · 访问量 782

猜你喜欢

转载自blog.csdn.net/er_ving/article/details/104823544
今日推荐