• Medium | LeetCode 148. 排序链表 | 归并排序(递归)


    148. 排序链表

    给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表

    进阶:

    • 你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?

    示例 1:

    img
    输入:head = [4,2,1,3]
    输出:[1,2,3,4]
    

    示例 2:

    img
    输入:head = [-1,5,3,4,0]
    输出:[-1,0,3,4,5]
    

    示例 3:

    输入:head = []
    输出:[]
    

    提示:

    • 链表中节点的数目在范围 [0, 5 * 104]
    • -105 <= Node.val <= 105

    解题思路

    方法一: 归并排序(递归)

    public ListNode sortList(ListNode head) {
        return sortList(head, null);
    }
    
    /**
     * 排序[head, tail)这部分的链表, 这是一个左闭右开的链表
     * @param head 链表头部
     * @param tail 链表尾部
     * @return 排序后的链表
     */
    public ListNode sortList(ListNode head, ListNode tail) {
        // 空链表直接返回
        if (head == null) {
            return head;
        }
        // 只有一个节点
        if (head.next == tail) {
            // 将next指针置位空
            head.next = null;
            return head;
        }
        // 快慢指针法找到链表的中间节点
        ListNode slow = head, fast = head;
        while (fast != tail) {
            // 慢指针每次走一步
            slow = slow.next;
            // 快指针每次走两步
            fast = fast.next;
            if (fast != tail) {
                fast = fast.next;
            }
        }
        // 将链表切成两块分别递归进行归并排序
        ListNode mid = slow;
        ListNode list1 = sortList(head, mid);
        ListNode list2 = sortList(mid, tail);
        return merge(list1, list2);
    }
    
    public ListNode merge(ListNode la, ListNode lb) {
        ListNode dumpHead = new ListNode();
        ListNode pre = dumpHead;
        ListNode pa = la, pb = lb;
        while (pa != null && pb != null) {
            if (pa.val <= pb.val) {
                pre.next = pa;
                pa = pa.next;
            } else {
                pre.next = pb;
                pb = pb.next;
            }
            pre = pre.next;
        }
        pre.next = (pa == null) ? pb : pa;
        return dumpHead.next;
    }
    
  • 相关阅读:
    JS模拟出 getElementsByClassName 功能
    如何为PDF文件添加书签
    Linux内核模块学习
    Linux字符设备驱动学习
    第53篇编译线程的初始化
    第51篇SharedRuntime::generate_native_wrapper()生成编译入口
    第50篇调用约定(2)
    第52篇即时编译器
    2021 阿里云容器服务年度盘点:企业级容器应用变化和技术趋势观察
    如何在零停机的情况下迁移 Kubernetes 集群
  • 原文地址:https://www.cnblogs.com/chenrj97/p/14907811.html
Copyright © 2020-2023  润新知