📑 题目:143. 重排链表

🚀 本题 LeetCode 传送门

题目大意

按照指定规则重新排序链表:第一个元素和最后一个元素排列在一起,接着第二个元素和倒数第二个元素排在一起,接着第三个元素和倒数第三个元素排在一起。

解题思路

最近简单的方法是先把链表存储到数组里,然后找到链表中间的结点,按照规则拼接即可。这样时间复杂度是 O(n),空间复杂度是 O(n)。

更好的做法是结合之前几道题的操作:链表逆序,找中间结点。

先找到链表的中间结点,然后利用逆序区间的操作,如 第 92 题 里的 reverseBetween() 操作,只不过这里的反转区间是从中点一直到末尾。最后利用 2 个指针,一个指向头结点,一个指向中间结点,开始拼接最终的结果。这种做法的时间复杂度是 O(n),空间复杂度是 O(1)。

代码

  1. package leetcode
  2. /**
  3. * Definition for singly-linked list.
  4. * type ListNode struct {
  5. * Val int
  6. * Next *ListNode
  7. * }
  8. */
  9. // 解法一 单链表
  10. func reorderList(head *ListNode) *ListNode {
  11. if head == nil || head.Next == nil {
  12. return head
  13. }
  14. // 寻找中间结点
  15. p1 := head
  16. p2 := head
  17. for p2.Next != nil && p2.Next.Next != nil {
  18. p1 = p1.Next
  19. p2 = p2.Next.Next
  20. }
  21. // 反转链表后半部分 1->2->3->4->5->6 to 1->2->3->6->5->4
  22. preMiddle := p1
  23. preCurrent := p1.Next
  24. for preCurrent.Next != nil {
  25. current := preCurrent.Next
  26. preCurrent.Next = current.Next
  27. current.Next = preMiddle.Next
  28. preMiddle.Next = current
  29. }
  30. // 重新拼接链表 1->2->3->6->5->4 to 1->6->2->5->3->4
  31. p1 = head
  32. p2 = preMiddle.Next
  33. for p1 != preMiddle {
  34. preMiddle.Next = p2.Next
  35. p2.Next = p1.Next
  36. p1.Next = p2
  37. p1 = p2.Next
  38. p2 = preMiddle.Next
  39. }
  40. return head
  41. }
  42. // 解法二 数组
  43. func reorderList1(head *ListNode) *ListNode {
  44. array := listToArray(head)
  45. length := len(array)
  46. if length == 0 {
  47. return head
  48. }
  49. cur := head
  50. last := head
  51. for i := 0; i < len(array)/2; i++ {
  52. tmp := &ListNode{Val: array[length-1-i], Next: cur.Next}
  53. cur.Next = tmp
  54. cur = tmp.Next
  55. last = tmp
  56. }
  57. if length%2 == 0 {
  58. last.Next = nil
  59. } else {
  60. cur.Next = nil
  61. }
  62. return head
  63. }
  64. func listToArray(head *ListNode) []int {
  65. array := []int{}
  66. if head == nil {
  67. return array
  68. }
  69. cur := head
  70. for cur != nil {
  71. array = append(array, cur.Val)
  72. cur = cur.Next
  73. }
  74. return array
  75. }