给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
-
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
//stem.out.println(head.val);
if(head == null) //头节点不存在
return null;
//计算链表的长度
int len = 1; //至少存在头节点
ListNode node = head;
while(node.next != null){
node = node.next;
len++;
}
//找出要删除的节点的前一个节点
int index = len - n; //对应着要删除的节点索引
if(index == 0) //删除头节点
return head.next;
//找要删除的节点的前一个节点
ListNode tmp = head;
for(int i = 0; i < index - 1; i++){
tmp = tmp.next;
}
tmp.next = tmp.next.next; //删除节点
return head;
}
/*
一次遍历,使用双指针(初始状态不同)
first为慢指针,初始指向头节点(第一个节点)或者索引为0的节点;
second为快指针,初始指向第n+1个节点或索引为n的节点;
两个指针每次移动一步:
当快指针second到达尾节点时,慢指针first刚好指向要删除的节点的前一个节点。
*/
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode first = head;
ListNode second = head;
for(int i = 0; i < n; i++){
second = second.next;
}
if(first.next == null) //仅一个节点
return null;
if(second == null) // 删除头节点
return head.next;
while(second.next != null){ //快指针second到达尾节点
first = first.next;
second = second.next;
}
first.next = first.next.next;
return head;
}
}
执行用时 :2 ms, 在所有Java提交中击败了92.11%的用户
内存消耗 :34 MB, 在所有Java提交中击败了95.83%的用户