码迷,mamicode.com
首页 > 编程语言 > 详细

LeetCode.148 排序链表

时间:2020-11-11 15:53:14      阅读:6      评论:0      收藏:0      [点我收藏+]

标签:不能   i++   lis   linked   head   空间   link   复杂度   vat   

题目描述:在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

 

O(nlogn)的时间复杂度第一时间就是归并排序了,然后要常数级空间,那就不能用递归。

 

原地归并

public ListNode sortList(ListNode head) {
        //如果只有一个节点直接返回
        if (head == null || head.next == null) {
            return head;
        }
        //获取链表长度
        int len = ListNodeLength(head);

        //定义哨兵节点用于返回
        ListNode dummyNode = new ListNode(-1);
        dummyNode.next = head;

        //循环时间复杂度O(logn),外层控制轮次,内层进行分割
        //i控制分割步长,指数级增长 1,2,4,8...步长超过链表长度就是排序完成
        for (int i = 1; i < len; i = i <<1) {
            //设置每一轮分割的起始节点
            ListNode pre = dummyNode;
            ListNode curNode = dummyNode.next;
            //每一轮都从curNode开始,也就是每一轮排序后的头节点,那么终止条件自然就是curNode != null
            while(curNode != null){
                ListNode leftNode = curNode;
                ListNode rightNode = cut(leftNode,i);
                //寻找分割的起始节点
                curNode = cut(rightNode,i);
                //通过pre节点指向排序后的头节点,作为下一轮分割的起始节点
                pre.next = mergeTwoLinkedList(leftNode,rightNode);
                while (pre.next != null){
                    pre = pre.next;
                }
            }
        }
        return dummyNode.next;
    }

    /**
     * 分割,断链。
     * @param head      进行断链操作的节点
     * @param step      分割步长,指数级增长,1-2-4-8...
     * @return          保存断链节点的下一个节点,作为下一组节点的开始节点
     */
    private ListNode cut(ListNode head, int step) {
        if (head == null){
            return null;
        }
        //设置分割步长step
        for (int i = 1; head.next != null && i < step; i++){
            head = head.next;
        }
        ListNode rightNode = head.next;
        //断链
        head.next = null;
        return rightNode;
    }

    public int ListNodeLength(ListNode head) {
        int length = 0;
        ListNode cur = head;
        while (cur != null) {
            cur = cur.next;
            length++;
        }
        return length;
    }

    public ListNode mergeTwoLinkedList(ListNode l1, ListNode l2) {
        ListNode dummyNode = new ListNode(-1);
        ListNode cur = dummyNode;
        while (l1 != null && l2 != null) {
            if (l1.val < l2.val) {
                cur.next = l1;
                l1 = l1.next;
            } else {
                cur.next = l2;
                l2 = l2.next;
            }
            cur = cur.next;
        }
        cur.next = l1 == null ? l2 : l1;
        return dummyNode.next;
    }

 

LeetCode.148 排序链表

标签:不能   i++   lis   linked   head   空间   link   复杂度   vat   

原文地址:https://www.cnblogs.com/pxy-1999/p/13764235.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!