前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【一天一大 lee】重排链表 (难度:中等) - Day20201020

【一天一大 lee】重排链表 (难度:中等) - Day20201020

作者头像
前端小书童
发布2020-11-03 10:12:15
3590
发布2020-11-03 10:12:15
举报
文章被收录于专栏:前端小书童

20201020

题目:

给定一个单链表 L:L0→L1→…→Ln-1→Ln , 将其重新排列后变为:L0→Ln→L1→Ln-1→L2→Ln-2→…

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

示例:

  1. 示例 1:
代码语言:javascript
复制
给定链表 1->2->3->4, 重新排列为 1->4->2->3.
  1. 示例 2:
代码语言:javascript
复制
给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.

抛砖引玉

思路:

重排后的链表是原链表中间隔插入末尾节点得到:

思路

  • 找到原链表中间节点,并以此位置作为后一半链表
  • 翻转后一半链表
  • 重构链表是从原链表开始每次分别从原链链表(beforeList)和后一半链表(afterList)中取一个节点重构 next, 直到遇到 null 结束

注意: 翻转后一半链表时会将原链表与后一半链表衔接的 next 指针置为 null 切断链表

抛砖引玉

代码语言:javascript
复制
/**
 * 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) {
  if (head == null) return
  // 翻转链表
  function reverseList(root) {
    let _result = null,
      node = root
    while (node != null) {
      // 逐个节点与其next指针上的节点nextTemp交换 -> 翻转链表
      let nextTemp = node.next
      node.next = _result
      _result = node
      node = nextTemp
    }
    return _result
  }

  let fast = head,
    beforeList = head,
    afterList = head
  // 将afterList指针指向后一半节点
  while (fast.next != null && fast.next.next != null) {
    afterList = afterList.next
    fast = fast.next.next
  }
  // 注意翻转后一半链表时会将原链表与后一半链表衔接的next指针置为null切断链表
  afterList = reverseList(afterList)

  let before = null,
    after = null
  while (beforeList != null && afterList != null) {
    before = beforeList.next
    after = afterList.next

    beforeList.next = afterList
    beforeList = before

    afterList.next = beforeList
    afterList = after
  }

  return head
}

存储链表节点

  • 使用数组存储节点
  • 声明两个指针分别从数组首尾开始构建 next
代码语言:javascript
复制
var reorderList = function(head) {
  if (head == null) return
  // 存储链表节点
  let list = []
  while (head !== null) {
    let temp = head.next
    head.next = null
    list.push(head)
    head = temp
  }
  // 按顺序重构next指针
  let start = 0,
    end = list.length - 1
  while (start < end) {
    list[start].next = list[end]
    // 数组前后两个指针不相邻时构建next
    if (end - start != 1) list[end].next = list[start + 1]
    start++
    end--
  }
  return list[0]
}

博客: 前端小书童

每天的每日一题,写的题解会同步更新到公众号一天一大 lee 栏目 欢迎关注留言

公众号:前端小书童

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端小书童 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目:
    • 示例:
    • 抛砖引玉
      • 存储链表节点
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档