148 Sort List

题目链接:https://leetcode.com/problems/sort-list/

题目:

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

解题思路:
排序 + O(n log n) = 快速排序,归并排序,堆排序
这道题选用归并排序
1. 先将链表从中间拆分为两个子链表(用 walker 和 runner 方法找到链表中点)
2. 递归两个子链表,递归终止条件为链表中元素的个数 <= 2
3. 对两个子链表进行归并排序
4. 为了方便链表的操作,在归并时新增一个头结点,将结点归并到头结点的后面

大神的思路是相同的,但他的代码实现比我的快一点,也附上他的代码
http://blog.youkuaiyun.com/linhuanmars/article/details/21133949

代码实现:
自己的实现:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode sortList(ListNode head) {
        if(head == null || head.next == null)
            return head;
        return helper(head);
    }
    ListNode helper(ListNode head) {
        if(head.next == null)
            return head;
        ListNode l1 = head;
        ListNode l2 = head.next;
        if(head.next.next != null) { // 找链表中点,将链表对半拆开进行递归
            ListNode walker = head.next;
            ListNode runner = head.next.next;
            while(runner.next != null && runner.next.next != null) {
                walker = walker.next;
                runner = runner.next.next;
            }
            ListNode q = walker.next;
            walker.next = null;
            l1 = helper(head);
            l2 = helper(q);
        }
        ListNode tmpH = new ListNode(0); // 启用头结点,方便操作
        ListNode p = tmpH;
        if(l1.next == l2 && l2.next == null) // 归并的两个链表是两个结点
            l1.next = null;
        while(l1 != null && l2 != null) { // 对两个链表进行归并
            ListNode tmp1 = l1.next;
            ListNode tmp2 = l2.next;
            if(l1.val <= l2.val) {
                p.next = l1;
                l1 = tmp1;
            } else {
                p.next = l2;
                l2 = tmp2;
            }
            p = p.next;
        }
        while(l1 != null) {
            p.next = l1;
            l1 = l1.next;
            p = p.next;
        }
        while(l2 != null) {
            p.next = l2;
            l2 = l2.next;
            p = p.next;
        }
        p.next = null;
        return tmpH.next;
    }
}
15 / 15 test cases passed.
Status: Accepted
Runtime: 9 ms

大神的实现:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode sortList(ListNode head) {  
        return mergeSort(head);  
    }  
    private ListNode mergeSort(ListNode head)  
    {  
        if(head == null || head.next == null)  
            return head;  
        ListNode walker = head;  
        ListNode runner = head;  
        while(runner.next!=null && runner.next.next!=null)  
        {  
            walker = walker.next;  
            runner = runner.next.next;  
        }  
        ListNode head2 = walker.next;  
        walker.next = null;  
        ListNode head1 = head;  
        head1 = mergeSort(head1);  
        head2 = mergeSort(head2);  
        return merge(head1, head2);  
    }  
    private ListNode merge(ListNode head1, ListNode head2)  
    {  
        ListNode helper = new ListNode(0);  
        helper.next = head1;  
        ListNode pre = helper;  
        while(head1!=null && head2!=null)  
        {  
            if(head1.val<head2.val)  
            {  
                head1 = head1.next;  
            }  
            else  
            {  
                ListNode next = head2.next;  
                head2.next = pre.next;  
                pre.next = head2;  
                head2 = next;  
            }  
            pre = pre.next;  
        }  
        if(head2!=null)  
        {  
            pre.next = head2;  
        }  
        return helper.next;  
    }  
}
15 / 15 test cases passed.
Status: Accepted
Runtime: 8 ms
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值