题目
思路
考察链表的基本操作以及快慢指针的应用,这道题不难,主要是需要注意细节和特殊情况。
快慢指针的思想: 由于链表在遍历之前是无法知道他的长度的,所以用一个快指针fast和慢指针slow,其中fast比slow先走n步,使得在fast走了n步之后,fast和slow的位置如下(红色位置标注):
此后就fast和slow就每次都同时走一步, 使得在fast到null的时候,slow正好到倒数第n个节点; 3是等待删除的节点,因此需要在slow到2的时候,就开始进行链表的删除操作,可以看到此时正好遍历到fast.next === null,此时可以退出循环,然后执行slow.next = slow.next.next, 进行链表节点的删除。
特殊情况:
链表只有5个节点,而删除的也是倒数第五个节点,如下图:
可以看到fast指向了null,因此如果继续判断fast.next,就会报错,所以在这种情况下,如果fast指向了null, 就直接的去掉第一个节点即可。
代码
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} n
* @return {ListNode}
*/
var removeNthFromEnd = function(head, n) {
let slow = head, fast = head;
while(n > 0){
fast = fast.next;
n--;
}
if(fast === null){
slow = head.next;
head.next = null;
return slow;
}
while(fast.next !== null){
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return head;
};