143. 重排链表

95 阅读1分钟

题目:
给定一个单链表 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
}