这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战
前言
链表操作对于前端开发人员感觉还是很陌生的,日常的工作中也不怎么接触链表相关的操作,这道题可以很好的让你对链表有一个认识,这道题是一个单链表的题目,我们首先要知道单链表只能从前一项找到后一项,而不能从后一项找到前一项,其次我们要知道链表的删除操作是什么,那就是n1.next=n1.next.next,这样就删除了原来n1后边的那个节点,下面我们来看题目
题目描述
给你一个链表,删除链表的倒数第 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]
解题思路
- 首先要知道链表的最后一个节点的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次的图:
n2移动n+1次的图:
代码如下:
/**
* @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运行结果如下:
总结
链表是一种神奇的数据结构,挺有意思的,后续会再更新几个链表的题,gogogo