题解 | 链表排序

链表排序

https://www.nowcoder.com/practice/d75c232a0405427098a8d1627930bea6

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     *
     * @param head ListNode类
     * @return ListNode类
     */
    public ListNode sortList (ListNode head) {
        // write code here
        if (head == null || head.next == null) {
            return head;
        }

        // 获取链表长度
        int length = getLength(head);

        ListNode dummy = new ListNode(0);
        dummy.next = head;

        // 从大小为1开始,每次翻倍
        for (int size = 1; size < length; size *= 2) {
            ListNode prev = dummy;
            ListNode curr = dummy.next;

            while (curr != null) {
                // 获取第一个子链表
                ListNode left = curr;
                ListNode right = split(left, size);
                curr = split(right, size);

                // 合并两个有序链表
                ListNode merged = merge(left, right);
                prev.next = merged;

                // 移动prev到合并后链表的末尾
                while (prev.next != null) {
                    prev = prev.next;
                }
            }
        }

        return dummy.next;
    }

    // 获取链表长度
    private int getLength(ListNode head) {
        int length = 0;
        while (head != null) {
            length++;
            head = head.next;
        }
        return length;
    }

    // 分割链表,返回后半部分的头节点
    private ListNode split(ListNode head, int size) {
        if (head == null) return null;

        // 移动到第size个节点
        for (int i = 1; i < size && head.next != null; i++) {
            head = head.next;
        }

        ListNode right = head.next;
        head.next = null; // 断开连接
        return right;
    }

    // 合并两个有序链表
    private ListNode merge(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode curr = dummy;

        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                curr.next = l1;
                l1 = l1.next;
            } else {
                curr.next = l2;
                l2 = l2.next;
            }
            curr = curr.next;
        }

        // 连接剩余部分
        if (l1 != null) {
            curr.next = l1;
        } else {
            curr.next = l2;
        }

        return dummy.next;
    }

}

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务