LeetCode19题:删除链表的倒数第N个结点

题目链接:(点击进入)

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;
        

    }
}
经验分享 程序员 微信小程序 职场和发展