LeetCode-148. 排序链表

版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/love905661433/article/details/84930685

题目

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

示例 1:

输入: 4->2->1->3
输出: 1->2->3->4

示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5

解题

  • 链表的特性, 不能随机访问节点
  • O(nlogn)级别的算法, 归并排序不需要随机访问节点, 所以可以使用过归并排序解决
  • 实际上快速排序也行, 但是快速排序在处理链表问题时, 一方面复杂一点, 一方面性能并没有归并排序高, 下面是归并排序代码:
class Solution {
    public ListNode sortList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        return mergeSort(head);
    }

    /**
     * 递归进行归并排序
     * @param head
     * @return
     */
    private ListNode mergeSort(ListNode head) {
        if (head.next == null ) {
            return head;
        }

        // 快慢指针
        ListNode slow = head;
        ListNode fast = head.next;
        // 快慢指针查找链表中间节点
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        ListNode q = slow.next;
        // 截断链表
        slow.next = null;
        // 递归进行归并排序
        ListNode p = mergeSort(head);
        q = mergeSort(q);
        // 对排序号的链表进行归并
        head = merge(p, q);
        return head;
    }

    /**
     * 归并
     * @param p
     * @param q
     * @return
     */
    private ListNode merge(ListNode p, ListNode q) {
        ListNode dummyHead = new ListNode(0);
        ListNode cur = dummyHead;
        while (p != null || q != null) {
            if (p == null) {
                cur.next = q;
                q = q.next;
            } else if (q == null) {
                cur.next = p;
                p = p.next;
            } else {
               if (p.val < q.val) {
                   cur.next = p;
                   p = p.next;
               } else {
                   cur.next = q;
                   q = q.next;
               }

            }

            cur = cur.next;
        }

        return dummyHead.next;
    }
}

猜你喜欢

转载自blog.csdn.net/love905661433/article/details/84930685
今日推荐