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

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

如:

1.例一:
输入: 4->2->1->3
输出: 1->2->3->4
2.例二:
输入: -1->5->3->4->0
输出: -1->0->3->4->5

思路是使用归并排序,将链表不断的分割,然后再合并。首先如果链表为空或者只有一个节点直接返回,begin1从头结点开始每次向后移动一个,begin2从第二个开始每次移动两个。当begin2的下一个为空(链表个数为偶数个)或者下下个为空(链表个数为奇数个)结束。
所有函数传入的都是链表的头结点。前一个链表的头即为sortList传入的结点,第二个链表的头结点即为begin1的下一个。
merge函数是将两个链表合并,传入两个链表的头节点,返回新链表的头结点。

class Solution {
    public ListNode sortList(ListNode head) {
        if(head==null||head.next==null){
            return head;
        }
        ListNode begin1 = head;
        ListNode begin2 = head.next;
        while(begin2.next!=null&&begin2.next.next!=null){
            begin1 = begin1.next;
            begin2 = begin2.next.next;
        }
        ListNode head2 = begin1.next;
        begin1.next = null;//将链表断开为两个,否则在归并时前一个链表不能到begin1结束
        ListNode a = sortList(head);
        ListNode b = sortList(head2);
        return merge(a,b);
    }
    private ListNode merge(ListNode a,ListNode b){
        ListNode p1 = a;
        ListNode p2 = b;
        ListNode fakeHead = new ListNode(-2);//建立一个临时节点用来建立新链表连接,将他指向的下一个节点返回即可。
        ListNode cur = fakeHead;
        while(p1!=null&&p2!=null){
            if(p1.val

你可能感兴趣的:(在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。)