143. 重排链表【链表】

143. 重排链表

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 * 10^4]
  • 1 <= node.val <= 1000

解题思路

注意:快慢指针找链表中间节点时,下面这个点很重要!!!

  • 链表长度为偶数时,如果用fast != nil && fast.Next != nil,则最终slow停在两个中间元素的后一个。如 1 2 3 4,最后slow会指着3

  • 如果用fast.Next != nil && fast.Next.Next != nil,则最终slow停在两个中间元素的前一个,如 1 2 3 4,最后slow会指着2。本题我们需要这种情况。

Go代码

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func reorderList(head *ListNode)  {
    if head == nil || head.Next == nil {
        return
    }
    // 以 1 2 3 4 举例,先将链表拆成两个链表,1 2和3 4
    // 然后后一个链表反转变为4 3,最后两个链表合并为 1 4 2 3
    // 1. 等分链表,常规套路,快慢指针
    slow ,fast := head,head
    // 注意:链表长度为偶数时,如果用fast != nil && fast.Next != nil,则最终slow停在两个中间元素的后一个
    // 如果用fast.Next != nil && fast.Next.Next != nil,则最终slow停在两个中间元素的前一个,本题我们需要这种情况
    for fast.Next != nil && fast.Next.Next != nil {
        fast = fast.Next.Next
        slow = slow.Next
    }

    // 切割成两个链表
    secondList := slow.Next
    slow.Next = nil

    // 后一个链表链表反转
    secondList = reverseList(secondList)

    // 拼接两个链表
    slow,fast = head,secondList
    for slow != nil && fast != nil {
        nxt := slow.Next
        secondNxt := fast.Next
        slow.Next = fast
        fast.Next = nxt
        slow = nxt
        fast = secondNxt
    }

}

func reverseList(head *ListNode) *ListNode  {
    // 头插法
    dummy := &ListNode{}
    dummy.Next = head 
    tail := head
    cur := head.Next
    for cur != nil {
        nxt := cur.Next
        cur.Next = dummy.Next
        dummy.Next = cur
        cur = nxt
        tail.Next = nxt
    }
    return dummy.Next
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值