标签:快排 输入 turn 时间复杂度 col div 需要 一个 while
在 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)时间复杂度下,首先想到七大排序中的归并排序,因为快排的需要双指针,指向首尾,单链表后一个元素没有前一个元素指针。
思路:和归并排序思路一样,归并思想不在此叙述,下面附上归并排序链接:https://www.cnblogs.com/du001011/p/10520272.html
代码如下:
/*
1.归并排序思想
2.找到中间节点
3.进行归并排序
*/
public static ListNode sortList(ListNode head) {
return head == null ? head:mergeSort(head);
}
//归并
private static ListNode mergeSort(ListNode head) {
if (head.next == null) {
return head;
}
//快慢指针找出中间结点,这块需要注意一点就是
//我们需要一个标记sign跟踪慢结点,当找出中间结点时,
//让中间结点前一结点即sign的下一个结点指向空
//这样做的目的是为了使前半部分链表和后半部分链表进行合并排序
//慢结点
ListNode s = head;
//快结点
ListNode f = head;
//标记结点
ListNode sign = null;
while (f.next != null) {
sign = s;
s = s.next;
f = f.next.next;
}
//标记结点下一个结点为空
sign.next = null;
ListNode left = mergeSort(head);
ListNode right = mergeSort(s);
return merge(left, right);
}
//合并两个链表
public static ListNode merge(ListNode l, ListNode r) {
ListNode dummyHead = new ListNode(0);
ListNode cur = dummyHead;
while (l != null && r != null) {
if (l.val <= r.val) {
cur.next = l;
cur = cur.next;
l = l.next;
} else {
cur.next = r;
cur = cur.next;
r = r.next;
}
}
if (l != null) {
cur.next = l;
}
if (r != null) {
cur.next = r;
}
return dummyHead.next;
}
标签:快排 输入 turn 时间复杂度 col div 需要 一个 while
原文地址:https://www.cnblogs.com/du001011/p/10610522.html