删除链表中的倒数第N个元素
删除链表中的元素的方法不尽相同,每个人应该都有自己的想法,这里我有两种自己的方法写出来分享一下:
1.方法1
我们可以注意到,删除倒数第N个元素,其实就是将链表中第(L-n+1)个元素略过,如下图:所以,要想解出来我们首先必须直到链表的长度L,也得设置一个头结点(链栈的头结点一般什么都不用存,他的设定只是为了一些特殊情况,比如链表中只有1个元素,或者要删除链表的第一个节点)帮助操作
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
//1.设置头结点
ListNode dummy=new ListNode(0);
dummy.next=head;
int length=0;
ListNode first=head;
//2.第一次遍历求出链表的长度length
int len=0;
while(first!=null){
first=first.next;
len++;
}
//3.第二次遍历删除元素
len=len-n;
first=dummy;
while(len>0){
first=first.next;
len--;
}
first.next=first.next.next;
return dummy.next;
}
}
2.方法二
在方法一的基础之上,可以利用双指针,只进行一次遍历,如图:设置双指针first,second都从头结点开始,删除倒数第N个元素时,先使first指针向前走(N+1)步,然后使first和second两个指针同时向后走,那么当first走到最后一个元素(first.next==null)的时候,second的下一个元素就刚好使需要删除的元素。
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy=new ListNode(0);
dummy=head;
ListNode first=dummy;
ListNode second=dummy;
//1.first向前走
for(int i=0;i<=n+1;i++){
first=first.next;
}
//2.first 和 second 一起走
while(first.next!=null){
first=first.next;
second=second.next;
}
//3.删除second的下一个元素
second.next=second.next.next;
}
return dummy.next;
}