力扣——删除链表的倒数第 N 个结点

92 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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
};