Loading

148. [链表][递归]链表排序

148. 链表排序

class Solution {
    public ListNode sortList(ListNode head) {
        // 1、递归结束条件
        if (head == null || head.next == null) {
            return head;
        }

        // 2、找到链表中间节点并断开链表 & 递归下探
        ListNode midNode = middleNode(head);
        ListNode rightHead = midNode.next;
        midNode.next = null;

        ListNode left = sortList(head);
        ListNode right = sortList(rightHead);

        // 3、当前层业务操作(合并有序链表)
        return mergeTwoLists(left, right);
    }

    //  找到链表中间节点(876. 链表的中间结点)
    private ListNode middleNode(ListNode head){
        // 这里让fast节点先走两步的原因:
        // fast和slow同一起点的话,对于节点数为偶数的链表,
        // 返回的是中间两个节点的第二个,无法正确拆分偶数链表。
        // 例如,一个链表只有1,2两个节点,如果用上述代码,返回的中间节点是节点2,无法拆分。
        // 为了返回正确,需要让fast先走一步或两步。

        // ListNode slow = head, fast = head.next;
        ListNode slow = head, fast = head.next.next;
        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }

    // 合并两个有序链表(21. 合并两个有序链表)
    private ListNode mergeTwoLists(ListNode l1, ListNode l2){
        ListNode sentinel = new ListNode(-1);
        ListNode curr = sentinel;
        while(l1 != null && l2 != null){
            if(l1.val < l2.val){
                sentinel.next = l1;
                l1 = l1.next;
            } else {
                sentinel.next = l2;
                l2 = l2.next;
            }
            sentinel = sentinel.next;
        }
        sentinel.next = l1 != null ? l1 : l2;
        return curr.next;
    }
}
posted @ 2020-10-24 11:08  上海井盖王  阅读(121)  评论(0)    收藏  举报