148. Sort List

108 阅读1分钟

Given the head of a linked list, return the list after sorting it in ascending order.

 

Example 1:

Input: head = [4,2,1,3]
Output: [1,2,3,4]

Example 2:

Input: head = [-1,5,3,4,0]
Output: [-1,0,3,4,5]

Example 3:

Input: head = []
Output: []

 

Constraints:

  • The number of nodes in the list is in the range [0, 5 * 104].
  • -105 <= Node.val <= 105

 

Follow up: Can you sort the linked list in O(n logn) time and O(1) memory (i.e. constant space)?

答案

使用归并排序

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func sortList(head *ListNode) *ListNode {

	if head == nil || head.Next == nil {
		return head
	}

	dummy := &ListNode{Val: -1, Next: head}
	curLen := 1
	fullLen := func(head *ListNode) int {
		count := 0
		for head != nil {
			count++
			head = head.Next
		}
		return count
	}(head)

	for curLen < fullLen {
		pre := dummy
		cur := dummy.Next

		for cur != nil {
			//第一个链表的头节点
			h1 := cur
			//找下一个链表头节点h2
			i := curLen

			for ; i > 0 && cur != nil; i-- {
				cur = cur.Next
			}

			len1 := curLen
			//只剩下一个链表
			if i > 0 {
				break
			}

			h2 := cur
			i = curLen
			for ; i > 0 && cur != nil; i-- {
				cur = cur.Next
			}

			len2 := curLen - i

			//合并
			for len1 > 0 && len2 > 0 {
				if h1.Val < h2.Val {
					pre.Next = h1
					pre = h1
					h1 = h1.Next
					len1--
				} else {
					pre.Next = h2
					pre = h2
					h2 = h2.Next
					len2--
				}
			}

			//衔接剩余的链表
			if len1 > 0 {
				pre.Next = h1
			} else {
				pre.Next = h2
			}

			//走完剩余的链表
			for len1 > 0 || len2 > 0 {
				pre = pre.Next
				len1--
				len2--
			}
			pre.Next = cur
		}
		//区间长度增加一倍
		curLen <<= 1
	}

	return dummy.Next
}