每日一题--删除链表的倒数第 N 个结点

266 阅读2分钟

这是我参与11月更文挑战的第21天,活动详情查看:[2021最后一次更文挑战]

题目

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

 

示例 1:

输入: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   思路

采取双重遍历肯定是可以解决问题的,但题目要求我们一次遍历解决问题,那我们的思路得发散一下。

我们可以设想假设设定了双指针 p 和 q 的话,当 q 指向末尾的 NULL,p 与 q 之间相隔的元素个数为 n 时,那么删除掉 p 的下一个指针就完成了要求。

设置虚拟节点 dummyHead 指向 head 设定双指针 p 和 q,初始都指向虚拟节点 dummyHead 移动 q,直到 p 与 q 之间相隔的元素个数为 n 同时移动 p 与 q,直到 q 指向的为 NULL 将 p 的下一个节点指向下下个节点

代码



我们可以设想假设设定了双指针 p 和 q 的话,当 q 指向末尾的 NULL,p 与 q 之间相隔的元素个数为 n 时,那么删除掉 p 的下一个指针就完成了要求。

 * 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) {
  let root = cur1 = cur2 = new ListNode(-1, head);
  // cur1 指针,负责探路,获取链表的总长度
  let length = 0; // 当前链表的总长度
  while (cur1.next) {
    cur1 = cur1.next;
    length ++;
  }
  // cur2 指针,负责删除指定节点
  let start = length - n; // 从哪个节点开始截
  while (start--) {
    cur2 = cur2.next
  }
  cur2.next = cur2.next.next; // 删除第 start 个节点
  return root.next; // 返回表头
};