返回

反转链表的指定范围(JavaScript实现)

前端

简介

反转链表的指定范围问题在编程面试中很常见,涉及链表的操作和算法设计。在本文中,我们将用JavaScript实现一种高效且通用的方法来反转链表的指定范围。

算法思路

  1. 首先,我们将链表分为两部分:第一部分是从头结点到需要反转的范围的起始结点的前一个结点;第二部分是从需要反转的范围的起始结点到链表的尾结点。
  2. 然后,我们将第二部分的链表反转。
  3. 最后,我们将反转后的第二部分链表连接到第一部分链表的尾结点上。

代码实现

/*
给定一个链表,反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。

1 ≤ m ≤ n ≤ 链表长度。

输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL
*/
const reverseBetween = (head, m, n) => {
  // 如果链表为空或m和n无效,则直接返回
  if (!head || m < 1 || n > head.length) {
    return head;
  }

  // 定义一个虚拟头结点,方便处理边界情况
  const dummy = new ListNode(0);
  dummy.next = head;

  // 找到要反转部分链表的前一个结点
  let prev = dummy;
  for (let i = 1; i < m; i++) {
    prev = prev.next;
  }

  // 反转要反转部分链表
  let start = prev.next;
  let end = start.next;
  while (m < n) {
    const next = end.next;
    end.next = start;
    start = end;
    end = next;
    m++;
  }

  // 将反转后的链表连接到原链表
  prev.next = start;

  // 返回反转后的链表
  return dummy.next;
};

算法分析

时间复杂度

算法的时间复杂度为O(n),其中n为链表的长度。这是因为算法需要遍历整个链表一次来找到要反转的部分链表,然后反转它,最后将它连接到原链表。

空间复杂度

算法的空间复杂度为O(1),因为算法只使用几个额外的变量来存储指针和临时数据。

总结

反转链表的指定范围问题是一个经典的链表操作问题。我们用JavaScript实现了一个高效的算法来解决这个问题,该算法的时间复杂度为O(n),空间复杂度为O(1)。