题目:
给定一个单链表 L 的头节点 head ,单链表 L 表示为:
L0 → L1 → … → Ln - 1 → Ln 请将其重新排列后变为:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … 不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/re… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法:
step1: 找到中点
step2: 中点开始右侧链表反转
step3:拼接链表
step4:检查边界条件
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reorderList(head *ListNode) {
midNode := head
preMidNode := &ListNode{Next:midNode}
h := head
nodeCount := 0
midCount := 1
// 1、找到中点,
for h != nil {
h = h.Next
nodeCount ++
mid := nodeCount / 2 + 1
for ; midCount < mid; midCount ++{
midNode = midNode.Next
preMidNode = preMidNode.Next
}
}
// 边界条件
if midCount == 1 {
return
}
preMidNode.Next = nil
// 2、右侧反转
right := reverse(midNode)
// 3、左侧右侧拼接
left := head
for left != nil && right != nil {
leftNext := left.Next
rightNext := right.Next
left.Next = right
// 左侧遍历完了的话,右侧节点可能还多出一个节点,此时leftNext == nil,不要设置right.Next = leftNext以免丢失最后一个节点
if leftNext != nil {
right.Next = leftNext
}
left = leftNext
right = rightNext
}
}
func reverse(head *ListNode) *ListNode {
// dummy := ListNode{Next:head}
h := head
var pre *ListNode
for h != nil {
next := h.Next
h.Next = pre
pre = h
h = next
}
return pre
}