删除倒数第 N 个节点

给定单向链表,删除指定的倒数第 N 个节点。
需要考虑链表长度大于、小于 N,假设 N 是有效的整数。

package com.loo;

public class RemoveNthFromEnd {

    public static void main(String[] args) {
        Node head = new Node(1);
        Node n1 = new Node(2);
        Node n2 = new Node(3);
        Node n3 = new Node(4);
        Node n4 = new Node(5);
        Node n5 = new Node(6);
        Node n6 = new Node(7);
        Node n7 = new Node(8);
        Node n8 = new Node(9);
        Node n9 = new Node(10);
        Node n10 = new Node(11);
        Node n11 = new Node(12);
        Node n12 = new Node(13);
        Node n13 = new Node(14);
        Node n14 = new Node(15);
        Node n15 = new Node(16);
        Node n16 = new Node(17);
        Node n17 = new Node(18);
        Node n18 = new Node(19);
        Node n19 = new Node(20);
        head.next = n1;
        n1.next = n2;
        n2.next = n3;
        n3.next = n4;
        n4.next = n5;
        n5.next = n6;
        n6.next = n7;
        n7.next = n8;
        n8.next = n9;
        n9.next = n10;
        n10.next = n11;
        n11.next = n12;
        n12.next = n13;
        n13.next = n14;
        n14.next = n15;
        n15.next = n16;
        n16.next = n17;
        n17.next = n18;
        n18.next = n19;
        /*while (head!=null) {
            System.out.println(head.value);
            head = head.next;
        }*/
        int N = 10; // 假设删除倒数第 N 个节点,这里倒数第 N 个节点是 10 ,

                         // 从链表最后节点从后往前数,第十个节点数值是 11.
        Node node = getRemoveNthFromEnd(head , N); // node 得到删除节点后的新节点
        while (node!=null) {
            System.out.println("node.value:" + node.value);
            node = node.next;
        }
    }
    
    public static Node getRemoveNthFromEnd(Node head , int n) {
      // 处理 n 可能是非法
        if (n <= 0) {
            return null;
        }
        Node node = new Node(0);
        node.next = head;
        Node preDelete = node;
        for (int i=0;i<n;i++) {
          // 如果链表长度小于 n ,那么就无法操作
            if (head == null) {
                return null;
            }
            head = head.next;
        }
        System.out.println("preDelete mid:" + preDelete.value + ",head:" + head.value);
        // 此时 head 是从链表头开始到第 n 个的节点位置
        // 这里需要清楚,head = null 也就是刚好链表长度等于 n ,即要删除链表第一个节点即可满足要求

        // 如果链表长度大于 n , 采用双链表计数,preDelete 和 head 相差正好是 n  个节点,
        // 不断往下走,head 和 preDelete 的距离保持 n 个节点距离不变,当 head 为 null 时即整个链表遍历完了,
        // 得到的 preDelete.next 正好是链表倒数第 n 个节点。
        while (head!=null) {
            head = head.next;
            preDelete = preDelete.next;
        }
//        System.out.println("preDelete.next.value:" + preDelete.next.value);
//        System.out.println("preDelete.next.next.value:" + preDelete.next.next.value);

       // 删除倒数第 n 个节点
        preDelete.next = preDelete.next.next;
        return node.next; // 返回表头
    }
    
    static class Node {
        int value;
        Node next;
        Node(int v) {
            value = v;
        }
    } 

}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值