📑 题目:148. 排序链表

🚀 本题 LeetCode 传送门

题目大意

链表的排序,要求时间复杂度必须是 O(n log n),空间复杂度是 O(1)

解题思路

这道题只能用归并排序才能符合要求。归并排序需要的 2 个操作在其他题目已经出现过了,取中间点是第 876 题,合并 2 个有序链表是第 21 题。

代码

  1. package leetcode
  2. /**
  3. * Definition for singly-linked list.
  4. * type ListNode struct {
  5. * Val int
  6. * Next *ListNode
  7. * }
  8. */
  9. func sortList(head *ListNode) *ListNode {
  10. length := 0
  11. cur := head
  12. for cur != nil {
  13. length++
  14. cur = cur.Next
  15. }
  16. if length <= 1 {
  17. return head
  18. }
  19. middleNode := middleNode(head)
  20. cur = middleNode.Next
  21. middleNode.Next = nil
  22. middleNode = cur
  23. left := sortList(head)
  24. right := sortList(middleNode)
  25. return mergeTwoLists(left, right)
  26. }
  27. func middleNode(head *ListNode) *ListNode {
  28. if head == nil || head.Next == nil {
  29. return head
  30. }
  31. p1 := head
  32. p2 := head
  33. for p2.Next != nil && p2.Next.Next != nil {
  34. p1 = p1.Next
  35. p2 = p2.Next.Next
  36. }
  37. return p1
  38. }
  39. func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
  40. if l1 == nil {
  41. return l2
  42. }
  43. if l2 == nil {
  44. return l1
  45. }
  46. if l1.Val < l2.Val {
  47. l1.Next = mergeTwoLists(l1.Next, l2)
  48. return l1
  49. }
  50. l2.Next = mergeTwoLists(l1, l2.Next)
  51. return l2
  52. }