题目描述
链接:排序链表
在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
示例1:
输入: 4->2->1->3
输出: 1->2->3->4
示例2:
输入: -1->5->3->4->0
输出: -1->0->3->4->5
解答思路
由于时间复杂度要求是O(n log n),所以我们可以用归并排序的思想来进行排序,而链表的节点交换都是原地进行的,所以我们只需要O(1)的空间复杂度。
我们可以用快慢指针来定位需要二分的操作,然后对慢指针前面的节点进行断链操作即可,然后将两条断裂的再进行合并。
代码
package Bytedance_LeetCode;
public class _148 {
public static class ListNode {
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
public static ListNode sortList(ListNode head) {
if (head == null) {
return head;
}
return mergeSort(head);
}
public static ListNode mergeSort(ListNode head) {
if (head.next == null) {
return head;
}
ListNode pre = null;
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
pre = slow;
slow = slow.next;
fast = fast.next.next;
}
pre.next = null;
ListNode l1 = mergeSort(head);
ListNode l2 = mergeSort(slow);
return merge(l1, l2);
}
public static ListNode merge(ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode(0);
ListNode cur = dummyHead;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
cur.next = l1;
cur = cur.next;
l1 = l1.next;
} else {
cur.next = l2;
cur = cur.next;
l2 = l2.next;
}
}
if (l1 != null) {
cur.next = l1;
}
if (l2 != null) {
cur.next = l2;
}
return dummyHead.next;
}
public static void printList(ListNode head) {
ListNode temp = head;
while (temp != null) {
System.out.print(temp.val + " ");
temp = temp.next;
}
System.out.println();
}
public static void main(String[] args) {
ListNode x = new ListNode(1);
x.next = new ListNode(2);
x.next.next = new ListNode(6);
x.next.next.next = new ListNode(4);
x.next.next.next.next = new ListNode(3);
x.next.next.next.next.next = new ListNode(0);
x.next.next.next.next.next.next = new ListNode(6);
printList(x);
ListNode sortHead = sortList(x);
printList(sortHead);
}
}