【LeetCode-面試演算法經典-Java實現】【023-Merge k Sorted Lists(合并k個排好的的單鏈表)】

來源:互聯網
上載者:User

標籤:數組   歸併   面試   演算法   offer   

【023-Merge k Sorted Lists(合并k個排好的的單鏈表)】 【LeetCode-面試演算法經典-Java實現】【所有題目目錄索引】 原題

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

題目大意

  合并k個排好的的單鏈表。分析和描述它的複雜性。

解題思路

  使用小頂堆來實現,先將K個鏈表的頭結點入堆,取堆頂元素,這個結點就是最小的,接著讓取出的這個結點的下一個結點入堆,再取堆頂元素,其為第二小的結點,一直這樣子操作,直到所有的結點都處理完,這樣就完成了鏈表的合并,更多細節請見代碼和注釋。假設K個鏈表一共有N個結點,時間複雜度是O(N*log(K)),空間複雜度是O(K)。

代碼實現

結點類

public class ListNode {    int val;    ListNode next;    ListNode(int x) {        val = x;    }}

演算法實作類別

public class Solution {   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 curr = head;        while (!minHeap.isEmpty()) {            ListNode node = minHeap.deleteTop();            // 結點的下一個結點不為空白就將下一個結點入堆            if (node.next != null) {                minHeap.add(node.next);            }            curr.next = node;            curr = node;        }        return head.next;    }    /**     * 小頂堆     *     * @param <T>     */    private static class MinHeap<T> {        // 堆中元素存放的集合        private List<T> items;        private Comparator<T> comp;        /**         * 構造一個椎,始大小是32         */        public MinHeap(Comparator<T> comp) {            this(32, comp);        }        /**         * 造詣一個指定初始大小的堆         *         * @param size 初始大小         */        public MinHeap(int size, Comparator<T> comp) {            items = new ArrayList<>(size);            this.comp = comp;        }        /**         * 向上調整堆         *         * @param index 被上移元素的起始位置         */        public void siftUp(int index) {            T intent = items.get(index); // 擷取開始調整的元素對象            while (index > 0) { // 如果不是根項目                int parentIndex = (index - 1) / 2; // 找父元素對象的位置                T parent = items.get(parentIndex);  // 擷取父元素對象                if (comp.compare(intent, parent) < 0) { //上移的條件,子節點比父節點小                    items.set(index, parent); // 將父節點向下放                    index = parentIndex; // 記錄父節點下放的位置                } else { // 子節點不比父節點小,說明父子路徑已經按從小到大排好順序了,不需要調整了                    break;                }            }            // index此時記錄是的最後一個被下放的父節點的位置(也可能是自身),            // 所以將最開始的調整的元素值放入index位置即可            items.set(index, intent);        }        /**         * 向下調整堆         *         * @param index 被下移的元素的起始位置         */        public void siftDown(int index) {            T intent = items.get(index);  // 擷取開始調整的元素對象            int leftIndex = 2 * index + 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 = index * 2 + 1; // 找到上移節點的左子節點的位置                } else { // 最小子節點不比父節點小,說明父子路徑已經按從小到大排好順序了,不需要調整了                    break;                }            }            // index此時記錄是的最後一個被上移的子節點的位置(也可能是自身),            // 所以將最開始的調整的元素值放入index位置即可            items.set(index, intent);        }        /**         * 向堆中添加一個元素         *         * @param item 等待添加的元素         */        public void add(T item) {            items.add(item); // 將元素添加到最後            siftUp(items.size() - 1); // 迴圈上移,以完成重構        }        /**         * 刪除堆頂元素         *         * @return 堆頂部的元素         */        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; // 返回堆頂元素        }        /**         * 判斷堆是否為空白         *         * @return true是空,false否         */        public boolean isEmpty() {            return items.isEmpty();        }    }}
評測結果

  點擊圖片,滑鼠不釋放,拖動一段位置,釋放後在新的視窗中查看完整圖片。

特別說明 歡迎轉載,轉載請註明出處【http://blog.csdn.net/derrantcm/article/details/47016131】

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

【LeetCode-面試演算法經典-Java實現】【023-Merge k Sorted Lists(合并k個排好的的單鏈表)】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.