题目链接:力扣(点击进入)
1.题目描述
给你一个链表,删除链表的倒数第n个结点,并返回链表的头结点,若为空链表则返回null
输出:head=[1,2,3,4,5],n=2
输出:[1,2,3,5]
?2.解题思想
? ? ? ? 方法一:利用遍历的思想,找到倒数第n个结点,使倒数第n个节点的前一个结点的next指向倒数第n个结点的下一个结点,然后返回头结点,就删除了倒数第n个节点 。然而在实际操作中,head可能为空,我们在head的前面插入一个结点newHead,左后返回newHead.next即可
class Solution {
public int length(ListNode head){ //利用遍历计算出链表的长度
int len=0;
for(ListNode cur=head;cur!=null;cur=cur.next){
len++;
}
return len;
}
public ListNode removeNthFromEnd(ListNode head,int n) {
int len=length(head);
ListNode newHead=new ListNode(-1); //为了防止链表为空链表,定义一个假的结点放在head前面,这样这条链表就不可能为空,结果只用返回newHeadnext即可
newHead.next=head; //将newHead和head连起来
ListNode cur=newHead;
if(k>len){
return null;
}
for(int i=1;i<len-n+1;i++){ //找到倒数第n个结点的前一个结点
cur=cur.next;
}
cur.next=cur.next.next; //使倒数第n个结点的前一个结点指向倒数第n个结点后面的结点
return newHead.next;
}
}
? ? ? ? 方法二:利用双指针的思想。p1,p2最初都指向head,然后让p1先向后移动n次,然后让两个同时移动,p1.next==null时,p2正好指向倒数第n个结点的前一个结点,此时让p2.next=p2.next.next即可。注意的是和方法一一样,防止为空链表,在head前面插入一个结点,最后返回插入结点的下一个结点就好了
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode p1=head;
ListNode p2=head;
ListNode fakeHead=new ListNode(-1); //防止链表为空链表,在前面插入一个结点
fakeHead.next=head;
for(int i=0;i<n;i++){
p1=p1.next;
if(p1==null){ //当p1==null是,正好删除的是第一个结点
return head.next;
}
}
while(p1.next!=null){
p1=p1.next;
p2=p2.next;
}
p2.next=p2.next.next;
return fakeHead.next;
}
}
? ? ?
|