问题:
给定链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
进阶:
可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?
示例 1:
输入:head = [4,2,1,3]
输出:[1,2,3,4]
示例 2:
输入:head = [-1,5,3,4,0]
输出:[-1,0,3,4,5]
示例 3:
输入:head = []
输出:[]
提示:
链表中节点的数目在范围 [0, 5 * 104] 内
-105 <= Node.val <= 105
解答思路:
以下是使用归并排序算法对链表进行排序的 Java 代码:
class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
public class SortLinkedList {
public ListNode sortList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode mid = findMiddle(head);
ListNode left = sortList(head);
ListNode right = sortList(mid);
return merge(left, right);
}
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;
}
ListNode mid = slow.next;
slow.next = null;
return mid;
}
private ListNode merge(ListNode left, ListNode right) {
ListNode dummy = new ListNode(0);
ListNode curr = dummy;
while (left!= null && right!= null) {
if (left.val < right.val) {
curr.next = left;
left = left.next;
} else {
curr.next = right;
right = right.next;
}
curr = curr.next;
}
curr.next = left!= null? left : right;
return dummy.next;
}
}
归并排序的基本思想是将链表分成两半,对两半分别排序,然后将排序后的两半合并起来。在这个算法中,我们使用快慢指针找到链表的中间节点,将链表分成两半,然后对这两半分别进行递归排序,最后将排序后的两半合并起来。
归并排序的时间复杂度为 O(n log n),空间复杂度为 O(log n),因为我们使用了递归调用。这满足了问题的进阶要求。
(文章为作者在学习java过程中的一些个人体会总结和借鉴,如有不当、错误的地方,请各位大佬批评指正,定当努力改正,如有侵权请联系作者删帖。)