给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
示例 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 * 10^4] 内
- -10^5 <= Node.val <= 10^5
进阶:你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?
解题:
func sortList(head *ListNode) *ListNode {
if head == nil {
return head
}
dummyHead := &ListNode{Next: head}
lastSorted, curr := head, head.Next
for curr != nil {
if lastSorted.Val <= curr.Val {
lastSorted = lastSorted.Next
} else {
prev := dummyHead
for prev.Next.Val <= curr.Val {
prev = prev.Next
}
lastSorted.Next = curr.Next
curr.Next = prev.Next
prev.Next = curr
}
curr = lastSorted.Next
}
return dummyHead.Next
}
昨天的方法拿过来结果超时了。。。
官方解答:
1.自顶向下归并排序
func merge(head1, head2 *ListNode) *ListNode {
dummyHead := &ListNode{}
temp, temp1, temp2 := dummyHead, head1, head2
for temp1 != nil && temp2 != nil {
if temp1.Val <= temp2.Val {
temp.Next = temp1
temp1 = temp1.Next
} else {
temp.Next = temp2
temp2 = temp2.Next
}
temp = temp.Next
}
if temp1 != nil {
temp.Next = temp1
} else if temp2 != nil {
temp.Next = temp2
}
return dummyHead.Next
}
func sort(head, tail *ListNode) *ListNode {
if head == nil {
return head
}
if head.Next == tail {
head.Next = nil
return head
}
slow, fast := head, head
for fast != tail {
slow = slow.Next
fast = fast.Next
if fast != tail {
fast = fast.Next
}
}
mid := slow
return merge(sort(head, mid), sort(mid, tail))
}
func sortList(head *ListNode) *ListNode {
return sort(head, nil)
}
2.自底向上归并排序
func merge(head1, head2 *ListNode) *ListNode {
dummyHead := &ListNode{}
temp, temp1, temp2 := dummyHead, head1, head2
for temp1 != nil && temp2 != nil {
if temp1.Val <= temp2.Val {
temp.Next = temp1
temp1 = temp1.Next
} else {
temp.Next = temp2
temp2 = temp2.Next
}
temp = temp.Next
}
if temp1 != nil {
temp.Next = temp1
} else if temp2 != nil {
temp.Next = temp2
}
return dummyHead.Next
}
func sortList(head *ListNode) *ListNode {
if head == nil {
return head
}
length := 0
for node := head; node != nil; node = node.Next {
length++
}
dummyHead := &ListNode{Next: head}
for subLength := 1; subLength < length; subLength <<= 1 {
prev, cur := dummyHead, dummyHead.Next
for cur != nil {
head1 := cur
for i := 1; i < subLength && cur.Next != nil; i++ {
cur = cur.Next
}
head2 := cur.Next
cur.Next = nil
cur = head2
for i := 1; i < subLength && cur != nil && cur.Next != nil; i++ {
cur = cur.Next
}
var next *ListNode
if cur != nil {
next = cur.Next
cur.Next = nil
}
prev.Next = merge(head1, head2)
for prev.Next != nil {
prev = prev.Next
}
cur = next
}
}
return dummyHead.Next
}