前置准备:
public class NodeTest {
static class MyNode {
int val;
MyNode preNode;
MyNode nextNode;
public MyNode(int val, MyNode preNode, MyNode nextNode) {
this.val = val;
this.preNode = preNode;
this.nextNode = nextNode;
}
;
}
public static void main(String[] args) {
MyNode head = new MyNode(1, null, null);
MyNode head1 = new MyNode(2, null, null);
MyNode head2 = new MyNode(3, null, null);
MyNode head3 = new MyNode(4, null, null);
head.nextNode = head1;
head1.preNode = head;
head1.nextNode = head2;
head2.preNode = head1;
head2.nextNode = head3;
head3.preNode = head2;
MyNode heads = deleteNodeFromBottom(head,3);
while (heads != null) {
System.out.println(heads.val);
heads = heads.nextNode;
}
}
普通解法:
//删除倒数第n个链表节点
private static MyNode deleteNodeFromBottom(MyNode head, int n) {
MyNode temp = head;
int len = 0;
//获取链表长度
while (temp != null) {
len++;
temp = temp.nextNode;
}
int deleteIndex = 1;
MyNode temp1 = head;
while (temp1 != null) {
if (len == n) {
//删除头节点
return temp1.nextNode;
} else {
if ((len - n) == (deleteIndex)) {
//删除非头节点
temp1.nextNode = temp1.nextNode.nextNode;
} else {
temp1 = temp1.nextNode;
}
deleteIndex++;
}
}
return head;
}
双指针解法:
//删除倒数第n个链表节点,双指针法删除
private static MyNode deleteNodeFromBottomByDoublePointer(MyNode head, int n) {
//构造虚拟头节点,方便操作
MyNode dummy = new MyNode(0,null,null);
dummy.nextNode = head;
MyNode fast = dummy;
MyNode slow = dummy;
//fast先行n步
while (--n!=0&&fast!=null){
fast = fast.nextNode;
}
//由于有虚拟节点,再走一步,
fast = fast.nextNode;
//此时快慢指针相隔n步,当fast移动到链表末尾,则slow指针便在倒数第n+1个
while (fast!=null){
slow = slow.nextNode;
fast = fast.nextNode;
}
//删除第n个
slow.nextNode = slow.nextNode.nextNode;
return dummy.nextNode;
}