删除链表倒数第n个节点
第一种方法:双指针
我们来讲一下双指针解决这个问题
思路:
1.假如我们要删除倒数第二个节点
2.我们设置两个指针node1=head和node2=head,设要删除倒数第n个节点;
3.我们先让node1移动n次 如图指向3
4.我们以node1为准当node1!=null并且node1.next!=null时node1=node1.next,node2=node2.next;
5.当循环执行完毕如图node1指向5,node2指向3我们要删除4节点,所以我们找到了4的前驱
6.我们让node2.next=node2.next.next;删除完成,返回头节点
7.我们这里有一种特殊情况当长度为2时,因为node1.next==null所以我们必须处理一下这个情况;
8.我们处理这种情况的方式很简单当要删除的时倒数第二个时我们直接让head=head.next;
我们来上代码:
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
if(head==null||head.next==null){
return null;
}
ListNode node1=head;//头指针1
ListNode node2=head;//头指针2
for(int i=0;i<n;i++){
node1=node1.next;//node1移动n次
}
while(node1!=null&&node1.next!=null){//以node1为准当node1==null或node1.next==null时停止循环
node1=node1.next;
node2=node2.next;
}
if(node1==null){//当长度为2并且要删除倒数第二个的时候
head=head.next;//直接让head=head.next;
return head;
}
node2.next=node2.next.next;//当node1.next==null时node2所指向的是要删除节点的前驱
return head;//返回头节点
}
第二种方法:
1.我们可以利用一个数学规律进行操作倒数第二个即就是6-2=4(size-n)即就是第四个也就找到了我们要删除的节点
2.我们找到位置后使用便利从0-3左闭右开也就是到下标2找到4的前驱我们就可以删除
3.在这里我们要求链表的长度
4.这里我们也要处理长度为2的情况当n==size时我们直接返回一个要删除的节点node就可以了
上代码:
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
int size=getSize(head);
if(head==null||head.next==null){
return null;
}
ListNode node=delete(n,head);
if(n==size)//当长度为2返回要删除的节点
{
return node;
}
return head;//长度大于2返回头节点
}
//删除节点
public ListNode delete(int index,ListNode head){
ListNode copyNode=head;
if(index<0||index>getSize(head)){//当n不满足规范时返回null
return null;
}
index=-index+getSize(head);//计算要删除数的下标
for(int i=0;i<index-1;i++){
copyNode=copyNode.next;//让节点走到要删除节点的前驱
}
ListNode delete=copyNode.next;//记录要删除的节点
copyNode.next=copyNode.next.next;//删除节点
return delete;//返回要删除的节点
}
//求链表长度
public int getSize(ListNode head){
ListNode flag=head;
int index=0;
while(flag!=null){
flag=flag.next;
index++;
}
return index;
}
}