删除链表中倒数第n个节点

给定一个链表,删除链表中倒数第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;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值