19. 删除链表的倒数第N个结点
题目链接
存储索引
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
List<ListNode> list = new ArrayList<>();
ListNode p = head;
while(p != null){
list.add(p);
p = p.next;
}
int sz = list.size();
if(sz - n == 0) return head.next;
if(n == 1) list.get(sz - n - 1).next = null;
else list.get(sz - n - 1).next = list.get(sz - n + 1);
return head;
}
}
- 要在一趟扫描的时间内找到倒数第N个结点,最直接的办法就是存储每个结点的索引,扫描结束后,直接删除倒数第N个即可
- 同时要注意判断,删除的结点时第一个和最后一个的特殊情况
快慢指针
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0, head);
ListNode first = head;
ListNode second = dummy;
for(int i = 0; i < n; i++)
first = first.next;
while(first != null){
first = first.next;
second = second.next;
}
second.next = second.next.next;
return dummy.next;
}
}
- 让第一个指针比第二个指针快n个,这样就只需要常数级的额外空间,就能找到倒数第N个结点,也省去了维护ArrayList的开销
- 这里在head结点前加入了dummy结点,省去了删除第一个结点的判断
- 因为不存在索引越界,所以也无需判断最后一个结点
- 第二个指针指向要删除结点的前一个结点,这样可以直接实现删除