Sort List

Sort a linked list in O(n log n) time using constant space complexity.

Example

Given 1->3->2->null, sort it to 1->2->3->null.

思路:如果空间不限制,完全可以把所有的val,拿出来排序之后,在从头到尾设置val,不用动指针

本题思路和一般的排序一样,用快速排序或者归并排序

归并排序思路:

需要写一个函数,将两个有序链表排序。这个可以使用最简单的方法非递归的

/**
 * Definition for ListNode.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int val) {
 *         this.val = val;
 *         this.next = null;
 *     }
 * }
 */ 
public class Solution {
    /**
     * @param ListNode l1 is the head of the linked list
     * @param ListNode l2 is the head of the linked list
     * @return: ListNode head of linked list
     */
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        // write your code here
        ListNode head1 = l1;
        ListNode head2 = l2;
        ListNode ans=new ListNode(0);
        ListNode anss=ans;
        while(head1!=null&&head2!=null){
            if(head1.val<head2.val){
                ListNode temp=head1.next;
                head1.next=null;
                ans.next=head1;
                head1=temp;
            }else{
                ListNode temp=head2.next;
                head2.next=null;
                ans.next=head2;
                head2=temp;
            }
            ans=ans.next;
        }
        while(head1!=null){
            ListNode temp=head1.next;
            head1.next=null;
            ans.next=head1;
            head1=temp;
            ans=ans.next;
        }
        while(head2!=null){
            ListNode temp=head2.next;
            head2.next=null;
            ans.next=head2;
            head2=temp;
            ans=ans.next;
        }
        return anss.next;
    }
}

递归版本的:

    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        // write your code here
        if(l1==null){
            return l2;
        }
        if(l2==null){
            return l1;
        }
        ListNode head;
        if(l1.val<l2.val){
            head=l1;
            head.next=mergeTwoLists(l1.next,l2);
        }else{
            head=l2;
            head.next=mergeTwoLists(l1,l2.next);
        }
        return head;
    }

这两种各有特点。

还需要用一个快慢指针的方法找中点。

剩下的就是归并的思路。

上完整代码

/**
 * Definition for ListNode.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int val) {
 *         this.val = val;
 *         this.next = null;
 *     }
 * }
 */ 
public class Solution {
    /**
     * @param head: The head of linked list.
     * @return: You should return the head of the sorted linked list,
                    using constant space complexity.
     */
    public ListNode sortList(ListNode head) {  
        // write your code here
        ListNode ans=sort(head);
        return ans;
    }
    
    public ListNode sort(ListNode head){
        if(head==null||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 head2=slow.next;
        slow.next=null;
        ListNode p1=sort(head);
        ListNode p2=sort(head2);
        ListNode p = mergeTwoLists(p1,p2);
        return p;
    }
    
    
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        // write your code here
        if(l1==null){
            return l2;
        }
        if(l2==null){
            return l1;
        }
        ListNode head;
        if(l1.val<l2.val){
            head=l1;
            head.next=mergeTwoLists(l1.next,l2);
        }else{
            head=l2;
            head.next=mergeTwoLists(l1,l2.next);
        }
        return head;
    }
}
原文地址:https://www.cnblogs.com/tobemaster/p/6034649.html