题目:
解题思路:
推导公式:通过举例,我们可以发现 n 和 链表长度 size 的关系:
size=5 的链表的倒数第 n 个数是正数第 size-n+1 个数.
比如,size为5的链表中倒数第3个数,正数第3(5-3+1);倒数第2的数是正数第4(5-2+1);
删除思路:因为是单链表,我们只能顺序遍历,从前往后,那么我们要做的就是控制遍历的次数。
引入中间指针temp(初始化为head)
每遍历一次就后移一位(temp=temp.next);
直到遍历到要删除的节点的前一个结点,退出遍历
删除操作:temp.next=temp.next.next;
需要注意的是:如果删除的结点是倒数第一个结点(最后一个节点),那么就不能使用这个语句,因为temp.next为null,temp.next.next 就是null.next,会报错,所以我们需要专门拎出来考虑。
/** * 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 temp = head; int size=0; //计算链表大小 while(temp!=null){ size++; temp=temp.next; } //如果链表只有一个元素 if(head.next==null && n==1){ return null; } temp=head; //如果删除的是首元结点(链表长度=n) if(n==size){ head=head.next; return head; } //如果删除的是链表最后一个结点 if(n==1){ for(int i=1;i<(size-n+1)-1;i++){ temp=temp.next; } temp.next=null; }else if(n>1){//如果删除的不是最后一个结点 for(int i=1;i<(size-n+1)-1;i++){ temp=temp.next; } temp.next=temp.next.next; } return head; } }
写在最后
这道题中,由于每次循环执行体为 temp=temp.next;它会指向指向下一个结点而不是当下这个结点,所以我们必须少遍历一次,在条件语句上 -1;