用双指针来遍历,得到倒数第 N - 1 个结点,然后进行删除即可
function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null {
// 虚拟头结点
// 简化删除头结点的时候的操作
const dummyHead = new ListNode()
dummyHead.next = head
let p = head
// 先遍历 n 次
for (let i = 0; i < n; i += 1) {
p = p.next
}
// 此时head 就是 lastN 的结点
// 但是因为要删除 lastN,所以记录 lastNPrev 即可
let lastNPrev = dummyHead
// 然后双指针一起移动
// 得到 lastNPrev 所在的结点
while (p) {
p = p.next
lastNPrev = lastNPrev.next
}
// 删除倒数第 n 个结点
lastNPrev.next = lastNPrev.next.next
return dummyHead.next
}
还是一样查找倒数第 N - 1 个结点,不过可以不用转换思维,提取一个查询的倒数第 N 个结点的方法来简化逻辑
function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null {
// 虚拟头结点
// 简化删除头结点的时候的操作
const dummyHead = new ListNode()
dummyHead.next = head
// 通过 findNthFromEnd 找到倒数第 N+1 个结点
const lastNPrev = findNthFromEnd(dummyHead, n + 1)
// 删除倒数第 n 个结点
lastNPrev.next = lastNPrev.next.next
return dummyHead.next
}
function findNthFromEnd(head: ListNode | null, n: number): ListNode | null {
let p = head
// 先遍历 n 次
for (let i = 0; i < n; i += 1) {
p = p.next
}
// 此时head 就是 lastN 的结点
let lastN = head
// 然后双指针一起移动
// 得到 lastN 所在的结点
while (p) {
p = p.next
lastN = lastN.next
}
return lastN
}