给定一个链表,删除链表中倒数第n个节点,返回链表的头节点。
给出链表1->2->3->4->5->null和 n = 2.
删除倒数第二个节点之后,这个链表将变成1->2->3->5->null.
O(n)时间复杂度 【最多只能遍历一遍链表】
/**
* Definition for ListNode.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int val) {
* this.val = val;
* this.next = null;
* }
* }
*/
public class Solution {
/**
* @param head: The first node of linked list.
* @param n: An integer.
* @return: The head of linked list.
*/
ListNode removeNthFromEnd(ListNode head, int n) {
// write your code here
if(head==null||n<1)
return head;
ListNode orghead=head;//用来保留头结点
ListNode flag=head;//用来记录
/*倒数第n个节点,即正数第length-n+1个节点,flag先移动n个节点,后移动到结尾刚好是移动length-n次
orghead在flag移动n次之后与n同步,则当flag到结尾时orghead刚好到第length-n个结点处 即要删除的前一个*/
while(n>0&&flag.next!=null){
flag=flag.next;
n--;
}
if(n==1&&flag.next==null)//要删除的是第一个节点时
return head.next;
while(flag.next!=null){
orghead=orghead.next;
flag=flag.next;
}
orghead.next=orghead.next.next;
return head;
}
}
【以下是网上学习的一种方法,但是会出现Runtime Error的错误。】
public class Solution {
/**
* @param head: The first node of linked list.
* @param n: An integer.
* @return: The head of linked list.
*/
public ListNode removeNthFromEnd(ListNode head, int n) {
if (remove(head, n) > 0) {//rank非负,表示要删除的是链表第一个节点
return head.next;
}
return head;
}
private int remove(ListNode node, int n) {
if (node.next == null) return 1;//最后一个即倒数第一个节点,rank 为1.
int rank;
rank = remove(node.next, n) + 1;
// the way to delete the nth node
// is to set the (n-1)th node's next
// as nth node's next
// [tricky] return a very big negtive number
// to indicate we are success
if (rank == n + 1) {//倒数第n+1个节点,即要删除的节点的前一节点
node.next = node.next.next;
return Integer.MIN_VALUE;//设置为最小值-2的31次方 只要进入这个if rank肯定是负数
}
return rank;
}
}