题目描述:
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
解题思路:
这是一道简单题。进阶要求使用一趟扫描实现,双指针是链表惯用方法。
定义两个指针,p、pre全都指向链表头部,然后pre指针先走n步,然后两个链表一起走,直到pre指针走到链表尾,这时p.next即为待删除结点。因为p、pre同时走,保持间距一直为n,则当pre走到链表尾时,p的下一个结点就是倒数第n个结点。
不过要注意,待删除结点是头结点的时候。也就是说假如链表长5,删除倒数第5个结点时。这时,对应的情况是 pre走到末尾的下一个结点,也就是已经为空,则说明 要删除的结点为头结点,这时直接返回head.next。即将头结点去除,头结点下一个结点变为新的头结点。
代码实现:
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode p = head;
ListNode pre = head;
while(n-- > 0) {
pre = pre.next;
}
if(pre == null) {
return head.next;
}
while(pre.next != null) {
p = p.next;
pre = pre.next;
}
ListNode toBeDeletedNode = p.next;
p.next = toBeDeletedNode.next;
toBeDeletedNode = null;
return head;
}