题目描述
删除链表中倒数的第n个节点
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
分析
- 先遍历一次获得链表长度length
- 然后length - n 获取target, 当前target < 0 时, p->next = p->next->next
源码
/**
* 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) {
let root = new ListNode("head");
root.next = head;
let getLengthsPointer = head;
let nums = 0;
while(getLengthsPointer) {
nums++;
getLengthsPointer = getLengthsPointer.next;
}
let pointer = root;
let target = nums - n;
while(pointer) {
target--;
if(target < 0) {
pointer.next = pointer.next.next ? pointer.next.next : null;
break;
}
pointer = pointer.next
}
return root.next;
};
进阶
一次遍历, 思想: 用双指针,第一个指针与第二个指针 相隔n, 当第一个指针到达结尾时,那么第二个指针也到了倒数第n个数的前一个了。
我们用上面 1 -> 2 -> 3 -> 4 -> 5 走一遍, n 为2
- first 指向 3 , second 指向 head, 同时向后移动
- 当first 指向到 null的时候,second 走到了 3,此时可以将second.next 指向 second.next.next
var removeNthFromEnd = function(head, n) {
let root = new ListNode("head");
root.next = head;
let first = root;
let second = root;
for (let i = 1; i <= n + 1; i++) {
first = first.next;
}
while (first != null) {
first = first.next;
second = second.next;
}
second.next = second.next.next;
return dummy.next;
}