[路飞]_今夜继续搞链表

262 阅读1分钟

143. 重排链表

题目

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

L0 → L1 → … → Ln - 1 → Ln 请将其重新排列后变为:

L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … 不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

第一思路

假设现在有链表:

graph LR
1 --> 3 --> 5 --> 7 --> 9 

首先想到链表反转

graph LR
9 --> 7 --> 5 --> 3 --> 1

发现不行,整个链表反转后,原来的表头也拿不到了;

整个链表反转不行,反转半个链表;

通过快慢指针,找到链表中间值;

然后将后半部分链表反转

graph LR
9 --> 7 --> 5 --> 1 --> 3

假设前半部分表头位node1;
后半部分表头位node2;

只需要枚举node1,node2即可解决问题

动态图

111.gif

静态图

未命名.009.jpeg

未命名.001.jpeg

未命名.002.jpeg

未命名.003.jpeg

未命名.004.jpeg

未命名.005.jpeg

未命名.006.jpeg

未命名.007.jpeg

未命名.008.jpeg

未命名.010.jpeg

未命名.011.jpeg

未命名.012.jpeg

代码

var reorderList = function (head) {
  if (head === null || head.next === null) return head
  let slow = head
  let fast = head
  while (fast && fast.next) {
    slow = slow.next
    fast = fast.next.next
  }
  const result = new ListNode(-1)
  result.next = head
  let node1 = head
  let node2 = reverse(slow)
  let next1 = node1.next
  let next2 = node2.next
  while (node2.next) {
    node1.next = node2
    node2.next = next1
    node1 = next1
    node2 = next2
    next1 = next1 ? next1.next : null
    next2 = next2 ? next2.next : null
  }

  return result.next
  function reverse(node) {
    let pro = null
    let curr = node
    let next = node.next
    while (curr) {
      curr.next = pro
      pro = curr
      curr = next
      next = next ? next.next : null
    }
    return pro
  }
}