1.题目描述
2.题解
i.暴力解法:
获取要删除的元素的位置(正数的位置,可由数学关系得到),用一个指针遍历到该元素的前一位删除即可。
ii.双指针法:
由上图可以发现,当要删除倒数第n个元素时,将fast移到正数第n个元素位置,再同时将slow和fast一起向后移直到fast移到最后一个元素则slow就指向了目标元素。
然而要执行删除操作需要slow指向目标元素的前一位(这样删除更方便),因此fast在一开始移动时应该多移一位,则这样slow就少移一位(即最终位置会在目标元素的前一位)。
最后删除操作就是slow的next指向目标元素的next即可。
3.代码示例
i.暴力解法
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
int length=getLength(head);//获取链表的长度
int loctaion=length-n;//指要删的元素的位置
ListNode index=new ListNode();
index=head;
//将指针不断向后遍历直到移到目标元素的前一位
for(int i=0;i<loctaion-1;i++){
index=index.next;
}
//若要删的是第一个元素,则直接将head向后移一位后返回即可
if(head!=null&&loctaion==0){
head=head.next;
return head;
}
//删除操作
if(index.next!=null&&index.next.next!=null)
index.next=index.next.next;
else
index.next=null;
return head;
}
//新定义的获取链表长度的方法
public int getLength(ListNode head){
ListNode listnode=new ListNode();
listnode=head;
int len=0;
while(listnode!=null){
listnode=listnode.next;
len++;
}
return len;
}
}
ii.双指针法
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode virtuaNode=new ListNode(0);//定义一个虚拟指针
ListNode fast=new ListNode();
ListNode slow=new ListNode();
virtuaNode.next=head;
fast=virtuaNode;
slow=virtuaNode;
//fast指针向后移动n位
for(int i=0;i<n;i++){
fast=fast.next;
}
//slow和fast指针一起向后移动直到fast指到最后一个元苏
while(fast.next!=null){
fast=fast.next;
slow=slow.next;
}
slow.next=slow.next.next;//删除操作
return virtuaNode.next;
}
}
4.问题总结
i.关于虚拟指针的作用
可以省略头节点为空的情况的判断。
ii.双指针法最后的返回值应该时虚拟节点的next
如果n=1,若返回head则最后会返回head指向的节点,而没有实现删除操作,而引入虚拟节点后,可以对虚拟节点进行删除操作:将虚拟节点的next指向head的next,最后输出虚拟节点的next则就得到删除第一个元素的链表了。这也间接体现了虚拟节点的好处。