LeetCode力扣之Merge k Sorted Lists

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.


import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * Created by lxw, liwei4939@126.com on 2018/3/5.
 */
/*
class ListNode{
    int val;
    ListNode next;

    public ListNode(int x){
        this.val = x;
    }
}
*/


public class MergeKSortedLists {
    /*
    使用小根堆进行操作,先将K个单链表的头结点入堆,取堆中最小的元素,
    此节点为合并后的头结点,将该节点的下一个节点插入该小根堆中,依次操作
    直到堆为空

     */
    public ListNode mergeKLists(ListNode[] lists){

        if (lists == null || lists.length < 1){
            return null;
        }

        if (lists.length == 1){
            return lists[0];
        }

        MinHeap<ListNode> minHeap = new MinHeap<ListNode>(new Comparator<ListNode>() {
            @Override
            public int compare(ListNode o1, ListNode o2) {

                if (o1 == null){
                    return -1;
                }
                if (o2 == null){
                    return 1;
                }

                return o1.val - o2.val;
            }
        });

        // 将数组中链表中的头结点入堆
        for (ListNode node : lists){
            if (node != null){
                minHeap.add(node);
            }
        }

        ListNode head = new ListNode(0);
        ListNode cur = head;

        while (!minHeap.isEmpty()){
            ListNode node = minHeap.deleteTop();

            if (node.next != null){
                minHeap.add(node.next);
            }

            cur.next = node;
            cur = node;
        }

        return head.next;
    }

    // 静态内部类(需要使用内部类时,优先选择静态内部类),小根堆
    private static class MinHeap<T>{

        private List<T> items;
        private Comparator<T> comp;

        public MinHeap(Comparator<T> comp){
            this(32, comp);
        }

        public MinHeap(int size, Comparator<T> comp){
            items = new ArrayList<>(size);
            this.comp = comp;
        }

        //向上调整堆
        public void siftUp(int index){
            T intent = items.get(index);

            while (index > 0){
                int patentIndex = (index - 1) /2;
                T parent = items.get(patentIndex);
                if (comp.compare(intent, parent) < 0){
                    items.set(index, parent);
                    index = patentIndex;
                } else {
                    break;
                }
            }
            items.set(index, intent);
        }

        // 向下调整堆
        public void SiftDown(int index){
            T intent = items.get(index);
            int leftIndex = index * 2 + 1;

            while (leftIndex < items.size()){
                T minChild = items.get(leftIndex);
                int minIndex = leftIndex;

                int rightIndex = leftIndex + 1;
                if (rightIndex < items.size()){
                    T rightChild = items.get(rightIndex);
                    if (comp.compare(rightChild, minChild) < 0){
                        minChild = rightChild;
                        minIndex = rightIndex;
                    }
                }

                if (comp.compare(minChild, intent) < 0){
                    items.set(index, minChild);
                    index = minIndex;
                    leftIndex = 2 * index + 1;
                } else {
                    break;
                }
            }

            items.set(index, intent);
        }

        // 向堆中添加元素
        public void add(T item){
            items.add(item);
            siftUp(items.size() - 1);
        }

        public T deleteTop(){
            if (items.isEmpty()){
                throw new RuntimeException("The heap is empty.");
            }

            T maxItem = items.get(0);
            T lastItem = items.remove(items.size() - 1);
            if (items.isEmpty()){
                return lastItem;
            }

            items.set(0,lastItem);
            SiftDown(0);
            return maxItem;
        }

        // 判断堆是否为空
        public boolean isEmpty(){
            return items.isEmpty();
        }

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值