给定单向链表,删除指定的倒数第 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;
}
}
}