题目地址:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/
思路:
两次遍历法
这个问题可以转变为删除从列表开头数起的第 (L - n + 1)个结点,其中 L 是列表的长度。只要我们得到列表的长度 L(遍历一次),再删除地L-n+1个节点即可,代码还是比较简单的,就不再写了
一次遍历法
这是面试官期待的解决方法。思路如下,我们可以定义两个指针。第一个指针从链表的头指针开始遍历向前走k-1,第二个指针保持不动,从第k步开始,第二个指针也开始从链表的头指针开始遍历。由于2个指针的距离保持在k-1,当第一个(走在前面的)指针到达链表的尾节点时,第二个(走在后面的)指针正好是倒数第n个节点,直接删除即可。
在6个节点的链表上找倒数第3个节点的过程
官方AC代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public ListNode removeNthFromEnd(ListNode head, int n) {
// 考虑到移除链表头节点的情况
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode first = dummy;
ListNode second = dummy;
// 移动前面的指针
for (int i = 1; i <= n + 1; i++) {
first = first.next;
}
// 同步移动2个指针
while (first != null) {
first = first.next;
second = second.next;
}
second.next = second.next.next;
return dummy.next;
}