LeetCode删除链表的倒数第 N 个结点 | 算法练习系列

319 阅读2分钟

这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战

前言

链表操作对于前端开发人员感觉还是很陌生的,日常的工作中也不怎么接触链表相关的操作,这道题可以很好的让你对链表有一个认识,这道题是一个单链表的题目,我们首先要知道单链表只能从前一项找到后一项,而不能从后一项找到前一项,其次我们要知道链表的删除操作是什么,那就是n1.next=n1.next.next,这样就删除了原来n1后边的那个节点,下面我们来看题目

题目描述

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

进阶:你能尝试使用一趟扫描实现吗?

示例 1:

链表图.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]

解题思路

  • 首先要知道链表的最后一个节点的next为null
  • 从题目来看,题目似乎并不难,考察的是对链表的简单操作,首先,我们可以通过for循环(循环一次,count加1,最后得到的就是链表的长度)来找出输入的链表的长度是多少,然后通过count-n+1就能得到要删除的那个节点在哪,假设count为5,n为2,那么要删除的的节点就是节点4位置,也就n1.next.next.next.next.
  • 上面的的进阶说到可以用一趟扫描来实现,那我们就来以一趟思路来解决,首先定义两个指针,n1,n2,分别指向dummy,通过for循环让n2先移动n次位置,然后同时移动n1和n2,直到n2.next为空停止,然后n1.next=n1.next.next就得到了删除之后的链表
  • 上边的方法是n2首先移动了n次,我们已可以让它移动n加一次,然后还是n1,n2一起移动,知道n2为null,下面的操作还是一样的,思路图和代码如下 n2移动n次的图: 链表图1.png n2移动n+1次的图:

链表图2.png

代码如下:

/**
 * @param {ListNode} head
 * @param {number} n
 * @return {ListNode}
 */
var removeNthFromEnd = function(head, n) {
    let dummy = new ListNode() //这里的dummy是为了解决边界问题,也就是当链表只有一个节点,并且n为1的时候
    dummy.next = head

    let n1= dummy
    let n2= dummy

    for(let i=0;i<n;i++){ //这是n2移动n次的情况,移动n+1次的情况只需改为i<=n即可,这是后下面的while要改为n2!==null
        n2=n2.next
    }

    while(n2.next!==null){
        n1= n1.next
        n2= n2.next
    }

    n1.next = n1.next.next
    return dummy.next
};

LeetCode运行结果如下:

删除链表.PNG

总结

链表是一种神奇的数据结构,挺有意思的,后续会再更新几个链表的题,gogogo