题目描述
给你一个链表,删除链表的倒数第 n **个结点,并且返回链表的头结点。
输入: head = [1,2,3,4,5], n = 2
输出: [1,2,3,5]
示例 2:
输入: head = [1], n = 1
输出: []
示例 3:
输入: head = [1,2], n = 1
输出: [1]
思路
- 采用虚拟头结点,这样删除头结点和其他节点的行为便一致了。
- 采用双指针法,定义两个指针:quick,slow。quick指针先行n步,然后slow和quick指针同步前进,直到quick指针到链表尾部。
小问题
这里有一个小问题,如果quick指针先行n步,然后slow和quick指针再一起前进,直到quick指针指向null.这时候我们找到的是倒数第n个节点,但是其实我们要操作的节点是倒数第n+1个节点。
所以我们需要quick 先行n+1步。这样slow找到的恰好是倒数第n+1个节点,即我们需要进行操作的节点。
代码
/**
* 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) {
// 创建虚拟头结点
var virtualHead=new ListNode("a");
virtualHead.next=head;
//定义快慢指针并初始化
var quick=virtualHead,slow=virtualHead;
n++;
//quick先行n+1步
while(n--&&quick!=null){
quick=quick.next;
}
//quick指针和slow指针一起移动
while(quick!=null){
quick=quick.next;
slow=slow.next;
}
//执行删除操作
slow.next=slow.next.next;
return virtualHead.next;
};