leetcode系列第四弹 💥「143 - 重排链表 」 🥒

162 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

hi, 我是小黄瓜没有刺。一枚菜鸟瓜🥒,期待关注➕ 点赞,共同成长~

leetcode链表系列第四篇!🎊

题目 👾

143. 重排链表

给定一个单链表 L 的头节点 head ,单链表 L 表示为:

L0L1 → … → Ln - 1Ln

请将其重新排列后变为:

L0LnL1Ln - 1L2Ln - 2 → …

不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

 

示例 1:

image.png

输入:head = [1,2,3,4]
输出:[1,4,2,3]

示例 2:

image.png

输入:head = [1,2,3,4,5]
输出:[1,5,2,4,3]

提示:

  • 链表的长度范围为 [1, 5 * 104]
  • 1 <= node.val <= 1000

思路 ✨

image.png

  1. 找到链表的中间值
let len = 0
// 计算链表的长度
for (let p = head; p !== null; p = p.next) {
    len++;
}
// 计算中间值
let midNum = len >> 1;

// js中的>>表示有符号位移,当操作一个正数时候:
10 >> 1
// 结果: 5
// 因为10的二进制是1010,往右移动一位就是101,十进制中代表的是5.

  1. 从中间的值将链表分为左右两个链表 只需要找到左链表的最后一个节点,然后赋值为null断开连接
let nxt = cur.next
cur.next = null
  1. 反转右边的链表
while(prev !== fast && cur) {
    let nxt = cur.next
    cur.next = prev
    prev = cur
    cur = nxt
}
  1. 分别从两边链表取值,先取左边的链表再取右边链表

解答 🎉

/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {void} Do not return anything, modify head in-place instead.
*/

var reorderList = function(head) {

    let len = 0
    // 取链表的总长度
    for (let p = head; p !== null; p = p.next) {
        len++;
    }
    // 取中间值
    let midNum = len >> 1;
    // 定义左右指针,此时初始值都赋值为头节点
    let fast = head, slow = head;
    
    // 将右指针移动到需要截取的右链表位置
    for (let i = 0; i < midNum; i++) {
        fast = fast.next;
    }
    
    // 移动左指针,将左指针移动到右链表的上一个节点
    while(fast.next !== null) {
        fast = fast.next
        slow = slow.next
    }
    
    let prev, cur = slow
    // 保存右链表
    let nxt = cur.next
    // 断开连接,分为左右两个节点 head 和 nxt
    cur.next = null
    cur = nxt
    
    
    // 反转右链表
    while(prev !== fast && cur) {
        let nxt = cur.next
        cur.next = prev
        prev = cur
        cur = nxt
    }
    
    // 交叉放置左右各个节点,prev为右链表第一个节点
    while(prev) {
        let h_node = head.next
        head.next = prev
        head = h_node

        let p_node = prev.next
        prev.next = head
        prev = p_node
    }
    return head
}

写在最后

leetcode系列第四篇!未来可能会更新实现mini-vue3javascript基础知识系列,希望能一直坚持下去,期待多多点赞🤗🤗,一起进步!🥳🥳