148. 排序链表

Given the head of a linked list, return the list after sorting it in ascending order.

Follow up: Can you sort the linked list in O(n logn) time and O(1) memory (i.e. constant space)?

Example 1:

148. 排序链表

Input: head = [4,2,1,3]
Output: [1,2,3,4]

Example 2:

148. 排序链表

Input: head = [-1,5,3,4,0]
Output: [-1,0,3,4,5]

Example 3:

Input: head = []
Output: []

Constraints:

  • The number of nodes in the list is in the range [0, 5 * 104].
  • -105 <= Node.val <= 105

排序链表。

题意是给你链表的头结点 head ,请将其按升序排列并返回排序后的链表,并满足时间O(nlogn),空间O(1)的要求。

按照题目要求,因为时间是nlogn,所以思路只能是merge sort。

链表归并排序有几个问题要解决:
1、找链表的中间位置:
用快慢指针法,当快指针到达终点时,慢指针来到的位置就是中间位置
   public ListNode getMiddle(ListNode head){
        ListNode f=head;
        ListNode s=head;
        while(f.next!=null&&f.next.next!=null){
            f=f.next.next;
            s=s.next;
           
        }
        return s;
    }
2、用中点位置,切分成左右两个链表,左右递归
       ListNode middle=getMiddle(head);
       ListNode next=middle.next;
       middle.next=null;
       ListNode l1=process(head);
       ListNode l2=process(next);

 

3、写归并过程(同数组一样)
  public ListNode mergeSort(ListNode l1,ListNode l2){
        if(l1==null && l2==null){
            return null;
        }
        ListNode dummy=new ListNode(0);
        ListNode cur=dummy;
        while(l1!=null && l2!=null){
            if(l1.val<=l2.val){
                cur.next=l1;
                l1=l1.next;
                cur=cur.next;
            }else{
                cur.next=l2;
                l2=l2.next;
                cur=cur.next;
            }
        }
        if(l1!=null){
            cur.next=l1;
        }else{
            cur.next=l2;
        }
        return dummy.next;
    }

  

完整代码如下:


class Solution {
    
    public ListNode sortList(ListNode head) {
      return process(head);
    }

    public ListNode process(ListNode head){
        if(head==null||head.next==null){
            return head;
        }
        //find mid node
       ListNode middle=getMiddle(head);
       ListNode next=middle.next;
       middle.next=null;
       ListNode l1=process(head);
       ListNode l2=process(next);
       return mergeSort(l1,l2);

    }

    public ListNode getMiddle(ListNode head){
        ListNode f=head;
        ListNode s=head;
        while(f.next!=null&&f.next.next!=null){
            f=f.next.next;
            s=s.next;
           
        }
        return s;
    }


    public ListNode mergeSort(ListNode l1,ListNode l2){
        if(l1==null && l2==null){
            return null;
        }
        ListNode dummy=new ListNode(0);
        ListNode cur=dummy;
        while(l1!=null && l2!=null){
            if(l1.val<=l2.val){
                cur.next=l1;
                l1=l1.next;
                cur=cur.next;
            }else{
                cur.next=l2;
                l2=l2.next;
                cur=cur.next;
            }
        }
        if(l1!=null){
            cur.next=l1;
        }else{
            cur.next=l2;
        }
        return dummy.next;
    }
}

  

148. 排序链表

上一篇:java基础之线程篇(三)


下一篇:Java 知识拓展