每天学习一点算法 2025/12/09
题目:删除链表中的节点
有一个单链表的 head,我们想删除它其中的一个节点 node。
给你一个需要删除的节点 node 。你将 无法访问 第一个节点 head。
链表的所有值都是 唯一的,并且保证给定的节点 node 不是链表中的最后一个节点。
删除给定的节点。注意,删除节点并不是指从内存中删除它。这里的意思是:
给定节点的值不应该存在于链表中。
链表中的节点数应该减少 1。
node 前面的所有值顺序相同。
node 后面的所有值顺序相同。
自定义测试:
对于输入,你应该提供整个链表 head 和要给出的节点 node。node 不应该是链表的最后一个节点,而应该是链表中的一个实际节点。
我们将构建链表,并将节点传递给你的函数。
输出将是调用你函数后的整个链表。
这个问题很简单,将节点的 val 和 next 修改为下一个节点的 val 和 next 即可。
function deleteNode(node: ListNode | null): void {
if (node?.next) {
node.val = node?.next?.val
node.next = node?.next?.next
}
};
这个太简单了,再来一道
题目:删除链表的倒数第N个节点
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
-
要找到倒数第
n个节点就必须知道链表的长度,我们可以先遍历一次链表获取长度,这样我就可以知道倒数第 n 个节点具体是哪一个了。function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null { if (!head || n <= 0) { return head; } let len = 0 let cur: ListNode | null = head // 遍历链表获取长度 while (cur) { len++ cur = cur.next } cur = head // 找到需要删除 node 的上一个几点执行删除操作 if (len === n) { if (head?.next) { head.val = head.next?.val head.next = head.next?.next || null } else { head = null } } else { for (let i = 0; i < len - n - 1; i++) { cur = cur?.next || null } if (cur?.next) { cur.next = cur?.next?.next } } return head }; -
我们还可以用一个栈来存储链表的节点,弹出是计数即可找到需要删除的节点。
function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null { if (!head || n <= 0) { return head; } const stack: ListNode[] = [] let cur: ListNode | null = head // 所有节点压栈 while (cur) { stack.push(cur) cur = cur.next } // 弹出 n 个节点 for (let i = 0; i < n; i++) { stack.pop() } // 此时栈顶的节点就是第n个节点的上一个节点 if (stack.length === 0) { head = head.next || null } else { const prev = stack[stack.length - 1] prev.next = prev.next?.next || null } return head } -
还可以使用快慢指针的方法,快指针先移动到第 n 个节点处,然后快慢指针一起移动,等到快指针到链表尾部时,慢指针指向就是倒数第 n 个节点的上一个节点,执行删除操作即可。
function removeNthFromEnd2(head: ListNode | null, n: number): ListNode | null { if (!head || n <= 0) { return head; } let fast: ListNode | null = head let slow: ListNode | null = head // 快指针移动到第n个节点 for (let i = 0; i < n; i++) { fast = fast?.next || null } if (!fast) { // fast如果是null n等于链表长度,删除head head = head.next || null } else { // 同时移动快慢指针直到快指针为null while (fast?.next) { fast = fast.next slow = slow?.next || null } slow?.next && (slow.next = slow.next.next) } return head }
每天学习一点算法 2025/12/09
题目:删除链表中的节点
有一个单链表的 head,我们想删除它其中的一个节点 node。
给你一个需要删除的节点 node 。你将 无法访问 第一个节点 head。
链表的所有值都是 唯一的,并且保证给定的节点 node 不是链表中的最后一个节点。
删除给定的节点。注意,删除节点并不是指从内存中删除它。这里的意思是:
给定节点的值不应该存在于链表中。
链表中的节点数应该减少 1。
node 前面的所有值顺序相同。
node 后面的所有值顺序相同。
自定义测试:
对于输入,你应该提供整个链表 head 和要给出的节点 node。node 不应该是链表的最后一个节点,而应该是链表中的一个实际节点。
我们将构建链表,并将节点传递给你的函数。
输出将是调用你函数后的整个链表。
这个问题很简单,将节点的 val 和 next 修改为下一个节点的 val 和 next 即可。
function deleteNode(node: ListNode | null): void {
if (node?.next) {
node.val = node?.next?.val
node.next = node?.next?.next
}
};
这个太简单了,再来一道
题目:删除链表的倒数第N个节点
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
-
要找到倒数第
n个节点就必须知道链表的长度,我们可以先遍历一次链表获取长度,这样我就可以知道倒数第 n 个节点具体是哪一个了。function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null { if (!head || n <= 0) { return head; } let len = 0 let cur: ListNode | null = head // 遍历链表获取长度 while (cur) { len++ cur = cur.next } cur = head // 找到需要删除 node 的上一个几点执行删除操作 if (len === n) { if (head?.next) { head.val = head.next?.val head.next = head.next?.next || null } else { head = null } } else { for (let i = 0; i < len - n - 1; i++) { cur = cur?.next || null } if (cur?.next) { cur.next = cur?.next?.next } } return head }; -
我们还可以用一个栈来存储链表的节点,弹出是计数即可找到需要删除的节点。
function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null { if (!head || n <= 0) { return head; } const stack: ListNode[] = [] let cur: ListNode | null = head // 所有节点压栈 while (cur) { stack.push(cur) cur = cur.next } // 弹出 n 个节点 for (let i = 0; i < n; i++) { stack.pop() } // 此时栈顶的节点就是第n个节点的上一个节点 if (stack.length === 0) { head = head.next || null } else { const prev = stack[stack.length - 1] prev.next = prev.next?.next || null } return head } -
还可以使用快慢指针的方法,快指针先移动到第 n 个节点处,然后快慢指针一起移动,等到快指针到链表尾部时,慢指针指向就是倒数第 n 个节点的上一个节点,执行删除操作即可。
function removeNthFromEnd2(head: ListNode | null, n: number): ListNode | null { if (!head || n <= 0) { return head; } let fast: ListNode | null = head let slow: ListNode | null = head // 快指针移动到第n个节点 for (let i = 0; i < n; i++) { fast = fast?.next || null } if (!fast) { // fast如果是null n等于链表长度,删除head head = head.next || null } else { // 同时移动快慢指针直到快指针为null while (fast?.next) { fast = fast.next slow = slow?.next || null } slow?.next && (slow.next = slow.next.next) } return head }
题目来源:力扣(LeetCode)
1010

被折叠的 条评论
为什么被折叠?



