一、题目

二、题解
解法 1
链表给了头节点,可以通过遍历链表的方式进行删除。想要删除指定节点,只需要找到其前一个节点,并让前一个节点指向待删除节点的后一个节点即可。
解法 2
双指针
因为涉及到可能会删除头节点,因此设置一个 dummy node。先让 l 和 r 都指向 dummy node,让 r 先走 n 步指到第 n 个节点,这样 l 和 r 之间的距离保持了 n。然后,让 l 和 r 都同时往后移,l 和 r 一直保持着 n 的距离。当 r 指向最后一个节点时,即 r 指向倒数第一个节点,而 l 和 r 的距离为 n,即 l 指向第 n + 1 个节点,使得 l.next = l.next.next,即可实现删除倒数第 n 个节点。
三、代码
解法 1 代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0, head);
int cnt = 0;
ListNode cur = head;
// 统计链表节点总个数
while (cur != null) {
cnt++;
cur = cur.next;
}
// 寻找待删除节点的前一个节点
ListNode pre = dummy;
for (int i = 0; i < cnt - n; i++) {
pre = pre.next;
}
// 删除
pre.next = pre.next.next;
return dummy.next;
}
}
解法 2 代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0, head);
ListNode l = dummy, r = dummy;
// r 先走 n 步,使得 r 领先 l n 的距离
for (int i = 0; i < n; i++) {
r = r.next;
}
// l 和 r 同时走,直到 r 走到最后一个节点,此时 l 走到倒数 n + 1 个节点
while (r.next != null) {
l = l.next;
r = r.next;
}
// 删除第 n 个节点
l.next = l.next.next;
return dummy.next;
}
}
807

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



