开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天,点击查看活动详情
题目
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
输入: head = [1,2,3,4,5], n = 2
输出: [1,2,3,5]
方法一:回溯
通过 returnNode 函数递归,在回溯阶段用 sum 记录倒数节点个数,如果数到我们所要的倒数第n个,用常规的删除链表节点方法,node.next = node.next.next,最后将节点返回即可。再用虚拟头节点解决删除第一个节点的问题。
var removeNthFromEnd = function(head, n) {
let sum = 0;
function returnNode(node){
if(node===null) return null;
let next = returnNode(node.next)
if(next !== null){
sum++;
if(sum === n){
node.next = node.next.next;
} else {
node.next = next;
}
}
return node;
}
let p = new ListNode(0,head)
returnNode(p)
return p.next
};
方法二:快慢指针
保持快慢指针差距是n,当快指针走到链表末尾的时候,慢指针就是在倒数第n个节点的位置上。我们为了方便删除节点,所以将快慢指针的间隔 +1,在循环结束时,慢指针就停在倒数第n+1个节点的位置,就可以用slow.next = slow.next.next删除节点。
考虑到还有删除节点为头节点的情况,用虚拟头节点来解决
while 循环里面,当快慢指针的间隔等于 n+1 开始,快慢指针就要同步向前移动
var removeNthFromEnd = function(head, n) {
let p = new ListNode(0,head)
let fast = p,slow = p,num=0;
while(fast){
fast = fast.next;
if(num >= n + 1){
slow = slow.next;
}
num++;
}
slow.next = slow.next.next;
return p.next
};