美文网首页
148. 排序链表

148. 排序链表

作者: justonemoretry | 来源:发表于2021-08-31 20:59 被阅读0次
    image.png

    解法

    自顶向下的归并,递归,会有O(logN)的空间复杂度

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode() {}
     *     ListNode(int val) { this.val = val; }
     *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
     * }
     */
    class Solution {
        public ListNode sortList(ListNode head) {
            return sort(head, null);
        }
    
        /**
         * 进行排序,但是尾部不取
         */
        public ListNode sort(ListNode head, ListNode tail) {
            if (head == null) {
                return head;
            }
            if (head.next == tail) {
                head.next = null;
                return head;
            }
            // 快慢指针找中间点
            ListNode fast = head;
            ListNode slow = head;
            while (fast != tail) {
                fast = fast.next;
                slow = slow.next;
                if (fast != tail) {
                    fast = fast.next;
                }
            }
            // 对两边的链表进行分别排序
            ListNode left = sort(head, slow);
            ListNode right = sort(slow, tail);
            // 进行merge操作
            ListNode dummyHead = new ListNode();
            ListNode temp = dummyHead;
            while (left != null && right != null) {
                if (left.val <= right.val) {
                    temp.next = left;
                    left = left.next;
                } else {
                    temp.next = right;
                    right = right.next;
                }
                temp = temp.next;
            }
            if (left != null) {
                temp.next = left;
            }
            if (right != null) {
                temp.next = right;
            }
            return dummyHead.next;
        }
    }
    

    自底向上,迭代解法,空间复杂度O(1)

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode() {}
     *     ListNode(int val) { this.val = val; }
     *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
     * }
     */
    class Solution {
        public ListNode sortList(ListNode head) {
            if (head == null) {
                return head;
            }
            int len = 0;
            ListNode temp = head;
            while (temp != null) {
                len++;
                temp = temp.next;
            }
    
            ListNode dummyHead = new ListNode();
            dummyHead.next = head;
            // 每次扩大一倍步长,从下向上merge
            for (int subLen = 1; subLen < len; subLen = subLen * 2) {
                // pre后续过程后移。但dummyHead不移动,每次指向排好的头结点
                ListNode pre = dummyHead;
                ListNode cur = dummyHead.next;
                // 遍历整条链表,直到为null
                while (cur != null) {
                    ListNode head1 = cur;
                    for (int i = 1; i < subLen && cur != null && cur.next != null; i++) {
                        cur = cur.next;
                    }
    
                    ListNode head2 = cur.next;
                    // 切断和head1之间的联系
                    cur.next = null;
                    cur = head2;
                    for (int i = 1; i < subLen && cur != null && cur.next != null; i++) {
                        cur = cur.next;
                    }
    
                    // 保存head2的下一位元素,并切断联系
                    ListNode next = null;
                    if (cur != null) {
                        next = cur.next;
                        cur.next = null;
                    }
    
                    // 合并
                    pre.next = merge(head1, head2);
                    // 取合并链表的末尾
                    while (pre.next != null) {
                        pre = pre.next;
                    }
                    // 接着合并
                    cur = next;
                }
            }
            return dummyHead.next;
        }
    
        public ListNode merge(ListNode left, ListNode right) {
            ListNode dummyHead = new ListNode();
            ListNode temp = dummyHead;
            while (left != null && right != null) {
                if (left.val <= right.val) {
                    temp.next = left;
                    left = left.next;
                } else {
                    temp.next = right;
                    right = right.next;
                }
                temp = temp.next;
            }
            if (left != null) {
                temp.next = left;
            }
            if (right != null) {
                temp.next = right;
            }
            return dummyHead.next;
        }
    }
    

    相关文章

      网友评论

          本文标题:148. 排序链表

          本文链接:https://www.haomeiwen.com/subject/jkcviltx.html