题目描述:给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点
为了解决一些极端情况:链表只有一个节点,会定义一个哑结点(需要明确的是,删除节点需要遍历到要删除节点的前一个节点)
方法一:二次遍历
思路:先遍历一次记录链表节点个数length,那么删除倒数第n个节点,就是删除第
(length-n+1)个节点
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
// 定义一个哑结点用于简化极端情况:链表只有一个结点(length=1,n=1情况)
ListNode temp = new ListNode(0);
temp.next = head;
int length = 0;
// 第一次遍历记录链表长度
ListNode curr = head;
while(curr != null) {
length++;
curr = curr.next;
}
// 删除正数第length-n个结点
length -= n;
curr = temp;
while(length > 0) { // 循环找到删除结点的前一个结点
length--;
curr = curr.next;
}
curr.next = curr.next.next;
return temp.next;
}
}
方法二:一次遍历
思路:定义2个指针,让first指针向前移动 (n+1) 位,之后两指针同时移动,当first指针为null时,second指针的下一个节点就是需要删除的节点
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
// 定义一个哑结点用于简化极端情况:链表只有一个结点(length=1,n=1情况)
ListNode temp = new ListNode(0);
ListNode first, second;
temp.next = head;
first = temp;
second = temp;
for(int i = 0; i < (n+1); i++) first = first.next;
while(first != null) {
second = second.next;
first = first.next;
}
second.next = second.next.next;
return temp.next;
}
}```