# [92] 反转链表 II

反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。

说明:

1 ≤ m ≤ n ≤ 链表长度。

示例:

输入: 1->2->3->4->5->NULL, m = 2, n = 4

输出: 1->4->3->2->5->NULL

这道题与 206.反转链表 可以合并在一起看,实际上就是206题的加难版。

核心问题不变,就是翻转链表的问题。解题方法可以参考206题。

本题多出来的难点在于,在翻转完m~n之间的链表后,怎样将翻转后的头尾节点与原来的链表联系上。这里就是一个逻辑问题了,先记录下翻转链表之前和之后的节点beforeStartafterEnd,翻转完后在连上头尾即可。

var reverseBetween = function(head, m, n) {
  if (m === n) return head;
  const dummy = new ListNode(null);
  dummy.next = head;

  let beforeStart = dummy;
  let cnt = 1;
  while (cnt < m) {
    beforeStart = beforeStart.next;
    cnt++;
  }
  let end = beforeStart;
  while (cnt <= n) {
    end = end.next;
    cnt++;
  }
  const start = beforeStart.next;
  const afterEnd = end.next;

  let pre = start;
  let cur = pre.next;
  while (cur !== end) {
    const next = cur.next;
    cur.next = pre;
    pre = cur;
    cur = next;
  }

  start.next = afterEnd;
  beforeStart.next = end;
  cur.next = pre;

  return dummy.next;
};

function ListNode(val) {
  this.val = val;
  this.next = null;
}