19. Remove Nth Node From End of List
关键点在于在头部节点添加一个 dummy node 即 dummy.next = head,这样在处理例如 [1] 1 还有 [1,2] 2 需要删除头节点的情况就不需要添加多余逻辑处理了,直接按照普通删除头节点就可以 cur.next = cur.next.next
解题思路
- 首先设置 dummy node
let dummy = { next: head } - 遍历计算链表长度
- 遍历到需要删除的节点的前一个节点即
const preNodeIndex = length - n次遍历后 - 删除指定的节点
cur.next = cur.next.next - 返回head节点
dummy.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} n
* @return {ListNode}
*/
const getLength = (head) => {
let length = 0
while (head) {
length++
head = head.next
}
return length
}
var removeNthFromEnd = function (head, n) {
let dummy = { next: head }
let cur = dummy
const length = getLength(head)
const preNodeIndex = length - n
for (let i = 1; i <= preNodeIndex; i++) {
cur = cur.next;
}
cur.next = cur.next.next;
return dummy.next
};
双指针
解题思路
- 设置 dummy 假节点 dummy = { next: head}
- 维护两个指针
slow fast,设置slow和fast之间相隔n个节点即需要n + 1次移动 - 设置完成后,移动两个指针,直到
fast.next === null - 那么 slow 指针所指的节点,既是需要删除的节点的前一个节点的位置
Demo
[1] 1 具体的执行流程
1.设置 slow 和 fast之间相隔 n 个 节点,经过n + 1次循环,即
while(n >= 0) { fast = fast.next n-- } n + 1后,** fast = null**
2.那么 while(fast !== null) { slow = slow.next fast = fast.next } 不需要循环了
- 直接删除
slow.next = slow.next.next即可
代码
/**
* 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} n
* @return {ListNode}
*/
var removeNthFromEnd = function (head, n) {
let dummy = { next: head }
let slow = dummy
let fast = dummy
while(n >= 0) {
fast = fast.next
n--
}
while(fast !== null) {
slow = slow.next
fast = fast.next
}
slow.next = slow.next.next;
return dummy.next
};