题目
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
数据范围
链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
测试用例
示例1

java
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例2
java
输入:head = [1], n = 1
输出:[]
示例3
java
输入:head = [1,2], n = 1
输出:[1]
题解(双指针,博主捞比版本)
java
/**
* 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) {
if(head==null||head.next==null){
return null;
}
int temp=n;
ListNode pre=head;
boolean flag=false;
ListNode pos=null;
int len=0;
while(pre!=null){
len++;
pre=pre.next;
if(flag) pos=pos.next;
if(n>=0){
n--;
}
if(n<0&&flag==false){
pos=head;
flag=true;
}
}
if(len==temp){
head=head.next;
}else{
pos.next=pos.next.next;
}
return head;
}
}
题解2 (双指针,官方版)
java
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
// 1. 定义虚拟头节点,指向 head,方便处理删除头节点的情况
ListNode dummy = new ListNode(0, head);
ListNode fast = head;
ListNode slow = dummy;
// 2. 让快指针先走 n 步
for (int i = 0; i < n; i++) {
fast = fast.next;
}
// 3. 快慢指针同步移动,直到快指针走到末尾
// 此时 slow 会恰好停在待删除节点的前一个位置
while (fast != null) {
fast = fast.next;
slow = slow.next;
}
// 4. 执行删除
slow.next = slow.next.next;
return dummy.next;
}
}
思路
这道题依然很简单,对于链表的删除操作,在O1空间下,并且只扫描一次,可以使用双指针进行操作,如何使用双指针,看官解就行了,博主虽然也写出来了,效率也一样,但可读性太差,也完全不规范,建议记忆规范版本即可。