[路飞]_LeetCode题19删除链表的倒数第 N 个结点

188 阅读2分钟

题目描述

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

 

示例 1:

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]  

提示:

链表中结点的数目为 sz 1 <= sz <= 30 0 <= Node.val <= 100 1 <= n <= sz

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/re… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

删除链表倒数第n个节点,我们只需要找到要删除节点的前一个节点,题目就迎刃而解。

image.png 定义两个指针,从图中可以清晰地看出,n就是绿色(pre)与黄色(cur)指针中间的节点数,所以我们让cur先移动n次,与pre间隔n个节点,此时同时移动pre与cur,当cur走到null时,pre的位置即为删除点的前一个节点,我们做删除操作返回头节点即可。 需要注意的是链表节点数为1的情况,因为1<= n <= sz,所以该情况必然返回null。

题解代码

 * 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) {
  //当链表只有一个节点,根据条件,1<= n <= sz,此时删除后链表必为空
  if(!head.next) return null;

  //定义两个指针分别指向虚拟头结点pre和head节点cur
  let ret = new ListNode(-1,head),pre = ret,cur = head;

  //让cur指针走n次,与pre指针相隔n个节点
  for (let i = 0; i < n; i++) {
    cur = cur.next;
  }

  //让两个指针一起移动,直到cur指向null
  while(cur) cur = cur.next,pre = pre.next;
  
  //此时的pre指向的位置即为需要断开点的前一个节点,做断开操作
  pre.next = pre.next.next;
  return ret.next;
  
};