LeetCode刷题MEDIM篇 Sort List

题目

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

Example 1:

Input: 4->2->1->3
Output: 1->2->3->4

Example 2:

Input: -1->5->3->4->0
Output: -1->0->3->4->5

十分钟思考

对于nlogn的时间复杂度,必定采用递归,折半,分而治之的思想。从list中间劈开,然后递归分割,排序后逐次合并。

但是写代码,不知道具体怎么写,看了其他人的实现,思路是对的,自己尝试写一遍。尤其是从中间分割list的方法,利用快慢指针,很厉害。一定要学会这个方法,之前判断单链表是否有环,也是利用快慢指针。来,自己写一下。代码一次通过,没有一点问题。总结一下:

1,拆分list的方法,利用快慢指针

2  合并两个单链表,从小到大排序。首先建立一个dummy node,作为新链表的开头,然后一个新的curr指针,指向加入的node

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode sortList(ListNode head) {
        //分而治之,从中间分开list
        //基准条件
        if(head==null||head.next==null){
            return head;
        }
        ListNode fast=head;
        ListNode slow=head;
        ListNode pre=slow;
        while(fast!=null&&fast.next!=null){
            //记录断开位置
            pre=slow;
            slow=slow.next;
            fast=fast.next.next;
        }
        //断开list
        pre.next=null;
        //递归拆分
        ListNode nodeLeft=sortList(head);
        ListNode nodeRight=sortList(slow);
        //合并list,需要依次拼接,刚开始各有一个节点,然后会有多个,依次往上合并
        return merge(nodeLeft,nodeRight);
    }
    private ListNode merge(ListNode l1,ListNode l2){
        //一个dummynode,一个curr指针,依次比较添加到新链表,长度不同,剩下的加入就可以
        ListNode dummy=new ListNode(0);
        ListNode curr;
        curr=dummy;
        while(l1!=null&&l2!=null){
            if(l1.val<l2.val){
                curr.next=l1;
                l1=l1.next;
            }
            else{
                curr.next=l2;
                l2=l2.next;
            }
            curr=curr.next;
        }
        //如果长度不一样
        if(l1!=null){
            curr.next=l1;
        }
        if(l2!=null){
            curr.next=l2;
        }
        return dummy.next;
    }
    
}

猜你喜欢

转载自blog.csdn.net/hanruikai/article/details/86063582