删除链表的倒数第N个节点
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
1. 两次扫描,第一次确定长度,第二次通过长度遍历
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode nullNode = new ListNode(0);
nullNode.next = head;
ListNode node = head;
int length=0;
//一次遍历,获取链表长度
while(node!=null){
length++;
node = node.next;
}
//length为正序要删除的节点
length = length-n;
node = nullNode;
while (length>0){
length--;
//移动节点到length位置上
node = node.next;
}
//连接下一节点
node.next = node.next.next;
return nullNode.next;
}
}
2. 一次遍历,设定两个指针,一个指向链表头,另一个指向第n+1节点,这样两个指针之间间隔为n个节点,同时向前移动两个指针,当第二个指针指向尾节点,则第一个节点位置则是倒数第n个节点位置
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode node = new ListNode(0);
node.next = head;
//第一个指针
ListNode first = node;
//第二个指针
ListNode second = node;
for (int i=0;i<n+1;i++){
//先将第一个指针指到第n+1节点,这是两个指针之间相差n个节点
first = first.next;
}
//两个指针同时前进,直到第一个指针指向尾节点
while (first!=null){
first = first.next;
second = second.next;
}
//将第二个指针所处的节点连接到下下个节点
second.next = second.next.next;
//实现删除
return node.next;
}
}