排序

79 阅读1分钟

148. 排序链表

  • 题目要求o(nlogn)时间复杂度,第一时间想到二分,归并排序
  • 而有要求在o(1)空间时间复杂度完成,因此不能选用递归(logn栈空间消耗)的方式实现,只可以迭代了。
  • 要使用之前做过的一道算法---合并两个有序链表

image.png(图摘自leetcode-cn.com/problems/so…

class Solution {
    public ListNode sortList(ListNode head) {
        if(head==null) return head;
        ListNode tempNode=new ListNode(0,head);
        ListNode cur=head;
        ListNode pre;
        ListNode next;
        //求链表总长
        int len=0;
        while(cur!=null){
            len++;
            cur=cur.next;
        }
        //11合并,22合并,44合并....直到所有有序
        for(int subLen=1;subLen<len;subLen<<=1){
            pre=tempNode;
            cur=tempNode.next;
            while(cur!=null){
                //找出第一段链表
                ListNode head1=cur;
                for(int i=1;i<subLen&&cur.next!=null;i++){
                    cur=cur.next;
                }
                
                ListNode head2=cur.next;
                //切断链表
                cur.next=null;
                //找出第二段链表
                cur=head2;
                for(int i=1;i<subLen&&cur!=null&&cur.next!=null;i++){
                    cur=cur.next;
                }
                next=null;
                //切断链表
                if(cur!=null) {
                    next=cur.next;
                    cur.next=null;
                }
                //合并两端有序链表
                ListNode listNode=mergeTwoSortedList(head1,head2);
                //修改指针,为下一次二分做准备
                pre.next=listNode;
                while(pre.next!=null) pre=pre.next;
                cur=next;
            }
        }
        return tempNode.next;
    }
    //合并两个有序链表
    public ListNode mergeTwoSortedList(ListNode head1,ListNode head2){
        ListNode dummyHead = new ListNode(0);
        ListNode temp = dummyHead, temp1 = head1, temp2 = head2;
        while (temp1 != null && temp2 != null) {
            if (temp1.val <= temp2.val) {
                temp.next = temp1;
                temp1 = temp1.next;
            } else {
                temp.next = temp2;
                temp2 = temp2.next;
            }
            temp = temp.next;
        }
        if (temp1 != null) {
            temp.next = temp1;
        } else if (temp2 != null) {
            temp.next = temp2;
        }
        return dummyHead.next;
    }
}