import java.util.*;
/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    public ListNode sortCowsIV(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        
        ListNode mid = findMiddle(head); // 找到链表中点
        ListNode secondHalf = mid.next; // 将链表分为两部分
        mid.next = null;
        
        ListNode sortedFirstHalf = sortCowsIV(head); // 递归排序前半部分链表
        ListNode sortedSecondHalf = sortCowsIV(secondHalf); // 递归排序后半部分链表
        
        return merge(sortedFirstHalf, sortedSecondHalf); // 合并两个有序链表
    }
    
    private ListNode findMiddle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        
        while (fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        
        return slow;
    }
    
    private ListNode merge(ListNode l1, ListNode l2) {
        if (l1 == null) {
            return l2;
        }
        if (l2 == null) {
            return l1;
        }
        
        ListNode dummy = new ListNode(0);
        ListNode current = dummy;
        
        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                current.next = l1;
                l1 = l1.next;
            } else {
                current.next = l2;
                l2 = l2.next;
            }
            current = current.next;
        }
        
        if (l1 != null) {
            current.next = l1;
        }
        if (l2 != null) {
            current.next = l2;
        }
        
        return dummy.next;
    }
}

该题考察排序。

本代码用的归并排序。

归并排序的基本思想是将链表逐步划分为更小的子链表,然后将子链表按照顺序合并,直到最终得到一个有序的链表。具体步骤如下:

  1. 如果链表为空或只有一个节点,则无需排序,直接返回链表。
  2. 使用快慢指针找到链表的中点,将链表分为两部分。
  3. 分别对两个子链表进行递归排序。
  4. 合并两个有序的子链表,得到一个排好序的链表。