给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
/**
* 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) {
//双指针
//a指针先走n个节点
ListNode a = head;
while (n-- > 0) {
a = a.next;
}
//如果走了n个位置后,a为null,说明要删除的是头节点,直接返回头节点的下个节点
if (a == null) {
return head.next;
}
//b从头开始,和a一起走,如果a的下一个节点为null,说明,b的下个节点就是要删除的节点
ListNode b = head;
while (a.next != null) {
a = a.next;
b = b.next;
}
//删除节点
b.next = b.next.next;
return head;
}
}
第一种做法,遍历一次记录长度,然后删除指定节点,很简单,这里就不写了,进阶做法是用双指针,第一个指针先走n步,如果再新建一个指针从头开始,当第一个指针的下个节点为null时,第二个指针的下个节点也就是要删除的节点,如果删除的节点为头节点,那么第一个指针再走完n步后,就会为null。