LeetCode 19-删除链表中的倒数第N个节点

 

1. 删除链表中的倒数第N个节点

public class RemoveNthFromEnd19 {
    //定义一个单链表
    public class ListNode {
        int val;           //当前节点值
        ListNode next;     //下一个节点值
        //构造方法 初始化当前节点值
        ListNode(int x) { val = x; }
    }

    /**删除链表中倒数第N个节点   方法1:单指针(两次循环)
     *时间复杂度 O(n) n:链表长度
     * @param head 给定的初始链表
     * @param n 要删除的倒数第几个节点
     * @return  dummy的哑元节点的下一个节点开始的链表
     *
     * 例:head链表是 1->2->3->4->5(要操作的链表) 删除倒数第2个节点4
     * dummy 链表是 0->1->2->3->4->5(在head的基础上加了一个哑元节点0)
     * 第一个while循环算出 length=3
     * 第二个while循环 first = first.next; 链表指针定位到节点3
     * first.next = first.next.next; 将3节点的下一个节点指向改为节点5,相当于删除了节点4
     * 返回dummy哑元节点的下一个节点的链表
     */
    public ListNode removeNthFromEnd01(ListNode head, int n) {
        ListNode dummy = new ListNode(0);
        //head和dummmy是同一个链表
        dummy.next = head;
        //第一个循环:算出正序要更改的节点序号  first链表是中间要操作的链表
        int length  = 0;
        ListNode first = head;
        while (first != null) {
            length++;
            first = first.next;
        }
        length -= n;    //删除倒数第n个节点  等价于删除正序 (lenght - n + 1)个节点
        //第二个循环:定位到要删除的节点的前一个节点
        //注意:dummy链表的头结点是0,是哑元节点
        first = dummy;
        while (length > 0) {
            length--;
            first = first.next;
        }
        first.next = first.next.next;
        return dummy.next;
    }

    /**删除链表中倒数第N个节点   方法2:双指针(一次循环)
     *时间复杂度 O(n) n:链表长度
     * @param head 给定的初始链表
     * @param n 要删除的倒数第几个节点
     * @return  dummy的哑元节点的下一个节点开始的链表
     */
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode first = dummy;
        ListNode second = dummy;
        // 将第一个指针移动到第 (n + 1)节点  使第一个指针和第二个指针间距保持为 n
        for (int i = 1; i <= n + 1; i++) {
            first = first.next;
        }
        // 同时移动两个指针 直到第一个指针指向链表结尾null,第二个指针此时要被删除节点的前一个节点处
        while (first != null) {
            first = first.next;
            second = second.next;
        }
        second.next = second.next.next;
        return dummy.next;
    }
}

方法1图解 :

 

方法2图解:

 

 

 

2. LeetCode代码测试

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值