1.题目:


2.难点:
难点受制于链表的结构,倒数不好处理,无法向前遍历,或者会有节点个数n个,要删除倒数第a个则会有删除顺数n-a+1个节点的方法,但这不知道长度不好实现(或者进行两次遍历第一次遍历进行对链表长度的确定第二次再用n–a+1来对节点进行遍历和删除)
但我们这边用一次遍历进行实现
3.方法实现原理:
用双指针方法。

n1不动,n2到3节点,n1和n2依次往后挪

最后挪动结果,n1则为要删除的点,n2指向空节点。n2-n1=a(要删除的倒数第a个点);

要注意点:n2指向空节点,n1和n2保持的距离一直相同。
删除节点:如果对4节点进行删除因为为单链表所以不能对前节点进行操作(对4节点来说要把前节点的链指向5)所以n1最后不应该指向4应该指向3这样就方便了删除节点操作
用n1.next=n1.next.next

4.两种方法实现:
1.多挪动一位:
对于图链表来说就是中间从隔一个节点变成隔两个节点,最后用n1.next=n1.next.next进行删除节点操作

2.后不指向空节改变n2的结束点,最点最后用n1.next=n1.next.next进行删除节点操作

边界问题:
1.链表只有一个节点

解决方法:在第一个节点前创建一个dummy的节点指向第一个节点,让n1,n2指向dummy空指针
5.代码:
(第二种实现方法)
/**
* 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 dummy=new ListNode();
dummy.next=head;
let n1=dummy;
let n2=dummy;
for(let i=0;i<n;i++)
{
n2=n2.next;
}
while(n2.next!==null)
{
n1=n1.next;
n2=n2.next;
}
n1.next=n1.next.next;
return dummy.next;
};
(第一种实现方法)
/**
* 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 dummy=new ListNode();
dummy.next=head;
let n1=dummy;
let n2=dummy;
for(let i=0;i<=n;i++)
{
n2=n2.next;
}
while(n2!==null)
{
n1=n1.next;
n2=n2.next;
}
n1.next=n1.next.next;
return dummy.next;
};
这篇博客介绍了如何使用双指针方法删除单链表中的倒数第n个节点。难点在于链表的不可逆遍历,但通过设置两个指针,可以一次遍历完成删除操作。具体实现包括两种方式:一是让指针n1比n2多移动一步,最后用n1.next=n1.next.next删除节点;二是改变n2的结束点,同样使用n1.next=n1.next.next进行删除。边界情况如链表只有一个节点时,需创建一个dummy节点作为起点。提供的代码展示了这两种实现方式。
1809





