最详解-JS如何交换链表中的节点

386 阅读2分钟

跟然叔学做动画的第一天

正题 JS如何交换链表中的节点

给你链表的头节点 head 和一个整数 k 。

交换 链表正数第 k 个节点和倒数第 k 个节点的值后,返回链表的头节点(链表 从 1 开始索引)。

示例:

image.png

输入: head = [1,2,3,4,5], k = 2
输出: [1,4,3,2,5]

由题意可知,当 k = 2 时,交换链表中第二个节点和倒数第二个节点,即将 24 的位置进行调换,但值得注意的是实际上链表第二个节点的next引用并没有改变,依然指向 3,第四个节点的next引用也没有发生改变,依然指向5。也就是说表面上是交换节点,但实际上是交换节点的 val 值,这一点的理解很关键。

依据以上分析我们可以按以下步骤进行分解:

  1. 找到第K个节点
  2. 找到倒数第K个节点
  3. 交换他们的 val 值

1.找到第K个节点

设p为链表的指针,遍历链表。设置计数器 count,第k个节点 front,当 count === k 时,p指针指向的节点即为第K个节点

如下: 1.gif

2.找到倒数第K个节点

这个是比较有意思的一种找法,因为我们知道链表只能从头遍历到尾才能知道链表的长度是多少,那么如何去找到倒数第K个节点呢?实际上是可以通过count计数同步遍历去寻找。下面来解释一下这个原理:

假设我要寻找倒数第一个节点,那么我们可以知道是最后一个,就是当链表遍历到最后即可。

假设要寻找倒数第二个节点,那么我的指针则需要移动 count - 2 个才能找到,以此类推。

如果不能够理解,那么用下面的图来说明:

2.gif

那么在上面的代码继续实现

如下:

3.gif

2.交换 val 值

找一个中间变量,直接交换即可 如下:

4.gif

完整代码:

var swapNodes = function (head, k) {
  // 设置计数器
  let count = 1
  // 设置遍历指针
  let p = head
  // 定义第K个节点
  let front = null
  // 定义倒数第K个节点
  let back = head
  while (p) {
    // count = k 是, p为第 K 个节点
    if (count === k) {
      // 找到第K个节点
      front = p
    }
    // 当 count > k 时, back 指针开始移动
    if (count > k) {
      back = back.next
    }
    p = p.next
    count++
  }
  // 交换节点 val
  let temp = front.val
  front.val = back.val
  back.val = temp

  // 完成 return
  return head
};

以上就是解决交换链表指定节点的思路和过程。PS:这算法不重要,突然感觉动画精致了有没有,解题5分钟,动画两小时!!所以你一定要看明白!!