LeetCode 148. 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

要求将列表排序,不适用额外的空间 且时间复杂度为
o(nlogn)
熟悉排序算法的话就知道要用到归并排序了,但在链表上直接进行归并排序的话还是要花一番功夫的。先看代码


    public ListNode sortList(ListNode head) {
        //head为空或者链表只有一个节点则直接返回
        if(head == null || head.next == null) return  head;

        ListNode tail = head.next;
        while (tail.next != null) {
            tail = tail.next;
        }
        //进行归并排序
        return mergeSortList(head,tail);

    }

    /**
     * 对链表排序,分别对左右递归操作
     * 如果begin == end 返回当前值
     *
     */
    public  ListNode mergeSortList(ListNode begin,ListNode end){
        if(begin == end){
            begin.next = null;
            return begin;
        }
        ListNode head = null;

        ListNode end1 = getMidNode(begin, end);
        ListNode begin2 = end1.next;
        //左右排完序后两个链表的头节点
        ListNode left = mergeSortList(begin,end1);
        ListNode right = mergeSortList(begin2,end);

        //选取头节点
        if(left.val < right.val){
            head = left;
            left = left.next;
        }else {
            head =right;
            right = right.next;
        }
        //设置当前指针
        ListNode cur = head;
        //合并两个链表
        while(left != null && right != null){
            if(left.val < right.val) {
                cur.next = left;
                left = left.next;
            }else{
                cur.next = right;
                right = right.next;
            }
            cur = cur.next;
        }
        if(left != null) cur.next = left;
        if(right != null) cur.next = right;

        return head;

    }



    ListNode getMidNode(ListNode begin,ListNode end){
        if(begin == end || begin.next == end) return begin;
        ListNode slow = begin, fast = begin;
        while(fast != end && fast.next != end){
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }

重点看函数public ListNode mergeSortList(ListNode begin,ListNode end)

这个函数就是将从begin开始到end的链表进行排序

无论end之后是否还有节点,排序完后我们都让这个链表成为一个独立的链表,即排序完最后的节点的下一个节点为空.

因此当一个链表的左右两端排序完成后我们就将原链表拆分成了两个完全独立的链表,这样之后合并就很方便了

ListNode getMidNode(ListNode begin,ListNode end)
就是获取链表中点了,没什么好说

再说一句,这题挺不错,复习了链表和归并排序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值