题目要求扫描一遍删除倒数第n
个结点,所以不建议算出链表的长度,好的解决方法是使用快慢指针,快慢指针一开始都指向第一个结点。为了能删除倒数第n
个结点, 我希望快指针为null
时,慢指针指向倒数第n+1
个结点,这样就能快速删除倒数第n
个结点。那么快指针就比慢指针快n+1
步。
假如我们定义链表长度为s
,那么倒数第n+1
个结点实际上是处于s-n
这个位置,也就是说慢指针需要走s-(n+1)
步。在循环中,快指针走了n+1
次时,慢指针才开始走。当然,如果要删除的是第一个结点,那么快指针就走不到n+1
次,只能走n
次,因为s=n
,而快指针最多走s
次。这时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) {
ListNode pre = head, cur = head;
while(cur != null){
if (n >= 0){
n--;
}else{
pre = pre.next;
}
cur = cur.next;
}
if (n >= 0){
head = head.next;
}else{
pre.next = pre.next.next;
}
return head;
}
}