143. 重排链表
给定一个单链表 L
的头节点 head
,单链表 L
表示为:
L0 → L1 → … → Ln - 1 → Ln
请将其重新排列后变为:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:
输入:head = [1,2,3,4]
输出:[1,4,2,3]
示例 2:
输入:head = [1,2,3,4,5]
输出:[1,5,2,4,3]
提示:
- 链表的长度范围为
[1, 5 * 104]
1 <= node.val <= 1000
方法1:转化为线性表,再按照要求链接节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
func reorderList(head *ListNode) { var nums []*ListNode dummy := head for dummy != nil { nums = append(nums, dummy) dummy = dummy.Next } l, r := 0, len(nums)-1 for l<r { nums[l].Next = nums[r] l++ if l == r { break } nums[r].Next = nums[l] r-- } nums[l].Next = nil return }
|
方法2:从链表中间切断,后半段逆序,然后再把二者合并
链表操作秀肌肉
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
func reorderList(head *ListNode) { if head == nil { return } mid := findMiddle(head) l1 := head l2 := mid.Next mid.Next = nil nl2 := reverse(l2) merge(l1, nl2) } func findMiddle(head *ListNode) *ListNode { slow, fast := head, head for fast.Next != nil && fast.Next.Next != nil { slow = slow.Next fast = fast.Next.Next } return slow } func reverse(head *ListNode) *ListNode { var pre, cur *ListNode = nil, head for cur != nil { nxt := cur.Next cur.Next = pre pre = cur cur = nxt } return pre } func merge(h1, h2 *ListNode) *ListNode { dummy := &ListNode{} t := dummy for h1 != nil && h2 != nil { t.Next = h1 t = t.Next h1 = h1.Next t.Next = h2 t = t.Next h2 = h2.Next } if h1 != nil { t.Next = h1 } else if h2 != nil { t.Next = h2 } return dummy.Next }
|