LeetCode 92. 反转链表 II|刷题打卡

149 阅读1分钟

题目描述

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

说明: 1 ≤ m ≤ n ≤ 链表长度。

示例:

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

解题思路

官方题解

方法一:迭代+直接

  • 分清楚四个边界,m - n 之间的链表直接反转
  • 加上一个虚拟节点处理 m = 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
 * @param {number} left
 * @param {number} right
 * @return {ListNode}
 */
var reverseBetween = function (head, m, n) {
  if (!head) {
    return null;
  }
  let cur = head;
  let pre = null;
  while (m > 1) {
    pre = cur;
    cur = cur.next;
    m--;
    n--;
  }
  // con 记录的是 m的前一个节点
  // tail 记录的是 n 的位置
  let con = pre;
  let tail = cur;
  // 反转链表的套路
  while (n > 0) {
    let next = cur.next;
    cur.next = pre;
    pre = cur;
    cur = next;
    n--;
  }
  // 当 m = 1 时,会出现边界的问题
  if (con !== null) {
    con.next = pre;
  } else {
    head = pre;
  }
  tail.next = cur;
  return head;
};

代码

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} m
 * @param {number} n
 * @return {ListNode}
 */
// todo 优化版
var reverseBetween = function (head, m, n) {
  let count = n - m;
  let p = (dummyHead = new ListNode());
  let pre, cur, tail, front;
  p.next = head;
  for (let i = 0; i < m - 1; i++) {
    p = p.next;
  }
  front = p;
  pre = tail = p.next;
  cur = pre.next;
  for (let i = 0; i < count; i++) {
    let next = cur.next;
    cur.next = pre;
    pre = cur;
    cur = next;
  }
  front.next = pre;
  tail.next = cur;
  return dummyHead.next;
};