148. 排序链表

148. 排序链表

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

示例1: 4 --> 2 --> 1 --> 3
1 --> 2 --> 3 --> 4

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

提示:

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

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

java:

class Solution {
    public ListNode sortList(ListNode head) {
        return toSortList(head, null);
    }

    // 递归,然后对列表进行分割
    public ListNode toSortList(ListNode head, ListNode tail) {
        // 判断条件,如果为空 直接就返回
        if (head == null) {
            return head;
        }
        if (head.next == tail) {
            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 = toSortList(head, mid);
        // 分割中间点以后的链表元素
        ListNode list2 = toSortList(mid, tail);
        // 对分割好的链表,进行排序,最后就可以返回结果
        ListNode sorted = merge(list1, list2);
        return sorted;
    }
    /**
    排序算法,定义一条新的链表,对前面两个进行排序 大的在后面,小的在前面
     */
    public ListNode merge(ListNode head1, ListNode head2) {
        ListNode dummyHead = new ListNode(0);
        // temp1 temp2 两个临时指针
        ListNode temp = dummyHead, temp1 = head1, temp2 = head2;
        while (temp1 != null && temp2 != null) {
            if (temp1.val <= temp2.val) {
                temp.next = temp1;
                temp1 = temp1.next;
            } else {
                temp.next = temp2;
                temp2 = temp2.next;
            }
            temp = temp.next;
        }
        if (temp1 != null) {
            temp.next = temp1;
        } else if (temp2 != null) {
            temp.next = temp2;
        }
        // 返回结果
        return dummyHead.next;
    }
}

解析:

​ 改题目解法比较复杂,主要难点在于给出的进阶操作,时间复杂度为O(n log n),因此使用了归并排序

归并排序:时间复杂度O(n log n),分的时间复杂度O(log n),合并的过程的复杂度是O(n)

先把链表切开,然后再进行合并的操作

posted @   十月的十日  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示
主题色彩