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

93 阅读1分钟

题目描述

给你一个链表,删除链表的倒数第 n **个结点,并且返回链表的头结点。

image.png

输入: head = [1,2,3,4,5], n = 2
输出: [1,2,3,5]

示例 2:

输入: head = [1], n = 1
输出: []

示例 3:

输入: head = [1,2], n = 1
输出: [1]

思路

  1. 采用虚拟头结点,这样删除头结点和其他节点的行为便一致了。
  2. 采用双指针法,定义两个指针:quick,slow。quick指针先行n步,然后slow和quick指针同步前进,直到quick指针到链表尾部。

小问题

这里有一个小问题,如果quick指针先行n步,然后slow和quick指针再一起前进,直到quick指针指向null.这时候我们找到的是倒数第n个节点,但是其实我们要操作的节点是倒数第n+1个节点。

image.png

所以我们需要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;
};