有序鏈表的合併的一種實現

概述:合併有序鏈表的一種實現

在Leetcode刷題的時候,碰到有序鏈表的合併問題,第21題是兩個鏈表的合併,第23提是k個鏈表的合併,第23題利用第21題的解法,將兩個鏈表合成一個,再把合成的鏈表作爲新鏈表和下一個鏈表合併即可。合併鏈表有很多方法:
a.將所有節點拆開,放到數組裏進行排序,再放回鏈表,這種方法實現最簡單,但是放棄了鏈表本身插入刪除成本低的優勢;
b.另一種方法是分別遍歷兩個鏈表,將節點從小到大一次加到另外一個新鏈表中,這種方法也比較簡單,定義兩個指針分別遍歷就好;
c.第三種方法是遍歷其中一張表,將節點數據插入到另一張鏈表對應的節點,這種方法的思路也簡單,很容易想到,但是實現起來會有一些坑,沒有IDE的情況下調試起來還是不太直觀的,其中需要特別注意的是頭插和尾插的處理。

代碼如下:

public class T23 {
    /**
     * 合併k個有序鏈表
     * @param lists 待合併的鏈表的數組
     * @return 合併後的有序鏈表第一個節點
     */
    public ListNode mergeKLists(ListNode[] lists) {
        ListNode p = null;
        for(ListNode node : lists){
            p = mergeTwoLists(p,node);
        }
        return p;
    }

    /**
     * 合併兩個有序鏈表
     * @param p 有序鏈表1
     * @param node 有序鏈表2
     * @return 鏈表2插入到鏈表1的合併結果
     */
    public static ListNode mergeTwoLists(ListNode p, ListNode node) {
        if (p == null) {
            return node;
        }
        if (node == null) {
            return p;
        }

        ListNode pFirst = p;
        ListNode prep = p;
        ListNode curNode = node;

        while (curNode != null) {
            node = node.next;
            while (p != null) {
                if (p.val < curNode.val) {
                    prep = p;
                    p = p.next;
                } else if (prep != p) {
                    curNode.next = prep.next;
                    prep.next = curNode;
                    break;
                } else {
                    break;
                }
            }
            // prep == p 說明在第一個節點之前插入
            if (prep == p) {
                curNode.next = prep;
                pFirst = curNode;
            }
            // p == null 說明在末尾插入
            if (p == null) {
                prep.next = curNode;
                curNode.next = null;
            }
            curNode = node;
            p = pFirst;
            prep = p;
        }
        return pFirst;
    }
}

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章