leetcode_23:Kマージソートリスト

まず、暴力行為

暴力説明するのはあまりない、私はコード、主に暴力行為2を書き込みません。

  1. 毎回トップに二つのリストの合併は、その後、新しいリストと他のリストのマージに進みます。これは、n-1回のマージが必要です。
  2. 一つ一つを比較する方法であり、最初のノードがKのリスト最小から選択して、新しいリンクされたリストに追加するたびに、繰り返し動作。

第二に、プライオリティキュー(小さなスタックの最上位)

実際には、暴力がどのように我々は、リストの最初のノードからKの最小値を選択するか、上記の方法2の変形です。この方法は、小さなパイル上部を作成し、その後、スタックの最上部からの時間を最小限にとることができます。ヒープの最上部は、要素を削除した後の要素を削除後続ノードを表示することがあり、そこには少しヒープの最上部に追加されます。コードは以下の通りであります:

public ListNode mergeKLists(ListNode[] lists) {
        if (lists.length == 0)
            return null;
        if (lists.length == 1)
            return  lists[0];
        //一定要注意新建优先级队列时候,初始化要用的参数
        //一个是堆的大小,一个是自定义的比较器    
        PriorityQueue<ListNode> queue = new PriorityQueue<>(lists.length, new Comparator<ListNode>() {
            @Override
            public int compare(ListNode o1, ListNode o2) {
                if (o1.val < o2.val)
                    return -1;
                else if (o1.val > o2.val)
                    return 1;
                else
                    return 0;
            }
        });
        //将所有不为null的队列头放到堆中
        for (ListNode node : lists) {
            if (node != null)
                queue.offer(node);
        }
        ListNode result = new ListNode(-1), p = result;
        while (!queue.isEmpty()) { //堆不为空时,不断地取堆顶
            ListNode popNode = queue.poll();
            p.next = popNode; //将堆顶数据(当前最小的)放到结果后面
            p = p.next;
            if (popNode.next != null) { //堆顶还有后继,则把后继加入到堆中
                queue.offer(popNode.next);
            }
        }
        return result.next;

第三に、合併マージ

常に2つのマージの間、二つのリストをマージしています。

public ListNode mergeKLists(ListNode[] lists) {
        if (lists.length == 0)
            return null;
        if (lists.length == 1)
            return  lists[0];
        int step = 1, index = 0;
        //很重要的一步,就是要知道index和step的条件
        while (index + step < lists.length) {
            for (; index+step < lists.length; index += 2*step) {
            	//将index和index+step位置的两个链表合并
                lists[index] = merge2Lists(lists[index], lists[index+step]);
            }
            index = 0;  //合并一次后,下标从0开始,step乘2
            step *= 2;
        }
        return lists[0];
    }

	//合并两个有序列表的过程
    public ListNode merge2Lists(ListNode list1, ListNode list2) {
        ListNode NewHead = new ListNode(0), head = NewHead;
        ListNode p1 = list1, p2 = list2;
        while (p1 != null && p2 != null) {
            if (p1.val <= p2.val) {
                head.next = p1;
                head = head.next;
                p1 = p1.next;
            } else {
                head.next = p2;
                head = head.next;
                p2 = p2.next;
            }
        }
        if (p1 != null) {
        	head.next = p1;
        }
        if (p2 != null) {
        	head.next = p2;
        }
        return NewHead.next;
    }
公開された96元の記事 ウォンの賞賛2 ビュー10000 +

おすすめ

転載: blog.csdn.net/reachwang/article/details/104223181