跟然叔学做动画的第一天
正题 JS如何交换链表中的节点
给你链表的头节点 head 和一个整数 k 。
交换 链表正数第 k 个节点和倒数第 k 个节点的值后,返回链表的头节点(链表 从 1 开始索引)。
示例:
输入: head = [1,2,3,4,5], k = 2
输出: [1,4,3,2,5]
由题意可知,当 k = 2 时,交换链表中第二个节点和倒数第二个节点,即将 2 和 4 的位置进行调换,但值得注意的是实际上链表第二个节点的next引用并没有改变,依然指向 3,第四个节点的next引用也没有发生改变,依然指向5。也就是说表面上是交换节点,但实际上是交换节点的 val 值,这一点的理解很关键。
依据以上分析我们可以按以下步骤进行分解:
- 找到第K个节点
- 找到倒数第K个节点
- 交换他们的 val 值
1.找到第K个节点
设p为链表的指针,遍历链表。设置计数器 count,第k个节点 front,当 count === k 时,p指针指向的节点即为第K个节点
如下:
2.找到倒数第K个节点
这个是比较有意思的一种找法,因为我们知道链表只能从头遍历到尾才能知道链表的长度是多少,那么如何去找到倒数第K个节点呢?实际上是可以通过count计数同步遍历去寻找。下面来解释一下这个原理:
假设我要寻找倒数第一个节点,那么我们可以知道是最后一个,就是当链表遍历到最后即可。
假设要寻找倒数第二个节点,那么我的指针则需要移动 count - 2 个才能找到,以此类推。
如果不能够理解,那么用下面的图来说明:
那么在上面的代码继续实现
如下:
2.交换 val 值
找一个中间变量,直接交换即可 如下:
完整代码:
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分钟,动画两小时!!所以你一定要看明白!!