Given a linked list, remove the n-th node from the end of list and return its head.
移除链表从后往前数第 n 个结点
Example:
Given linked list: 1->2->3->4->5, and n = 2.
After removing the second node from the end, the linked list becomes 1->2->3->5.
解析:
可以把 n 看做 n 长度的一条边,边右端点是尾节点简称 B ,边左边端点是要删掉的结点简称 A ,这三者组成了一把尺子。
当 A 从头结点出发时,B 在从前往后数第 n 个结点,A 走到下一个结点,B 在第 n + 1 个节点,当 B
到了尾节点,因为 AB 之间长为 n ,所以 A 也到了从后往前数第 n 个结点。
所以需要两个变量,一个变量让他快点跑到第 n 个结点,之后两个变量以同样的速度往后移动,直到快的那个变量遇到 null
值得注意的是链表的删除是需要用到被删除结点的前一个结点的,所以应该让慢的那个变量停在 n + 1 的结点上。
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @param {number} n
* @return {ListNode}
*/
var removeNthFromEnd = function(head, n) {
if(head == null) return head;
// 用假節點當首節點,方便操作
var node = new ListNode(0);
node.next = head;
var slow = node;
var fast = head;
// 快指針先跑n個節點
while(n > 0){
fast = fast.next;
n--;
}
// 因為快指針已經先跑n點,所以當快指針fast跑完,慢指針slow會在要移除的前一點上
while(fast){
fast = fast.next;
slow = slow.next;
}
if(slow.next == null){
slow.next = null ;
} else {
slow.next = slow.next.next;
}
return node.next;
};