对于这道题我首先想到的是双指针并且也正确解答了后发现其实我写的代码冗余了依然可以优化代码为单指针即可解题但看了题解之后发现快慢指针非常巧妙代码也非常简洁
单指针解法
1、定义一个虚拟节点vNode指向头结点
2、定义指针cur指向虚拟节点vNode
3、遍历链表得到链表的长度len
4、自定义变量m=len-n(也就是需
要删除的链表正数第m个节点的前一个节点)
5、移动cur指针至第m个节点
6、令cur指向需要删除节点的后一个节点即可也就是cur.next=cur.next.next
7、返回vNode.next即可解题
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {int len = 0;ListNode cur = head;while (cur != null) {len++;cur = cur.next;}int m = len - n;ListNode vNode = new ListNode();vNode.next = head;cur = vNode;for(int i=0;i<m;i++){cur=cur.next;}cur.next=cur.next.next;return vNode.next;}
}
快慢指针解法
1、定义虚拟节点vNode指向头结点
2、定义快慢指针fastIndex、slowIndex指向虚拟节点
3、令fastIndex移动n+1个单位
4、令fastIndex和slowIndex同步向后移动直至fastIndex指向null(此时slowIndex在删除节点的前一个节点)
5、令slowIndex.next=slowIndex.next.next
6、返回vNode.next即可解答
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {ListNode vNode=new ListNode();vNode.next=head;ListNode fastIndex=vNode;ListNode slowIndex=vNode;for(int i=0;i<n+1;i++){fastIndex=fastIndex.next;}while(fastIndex!=null){fastIndex=fastIndex.next;slowIndex=slowIndex.next;}slowIndex.next=slowIndex.next.next;return vNode.next;}
}
总结:快慢指针中的fastIndex向后移动n+1个单位后那么slowIndex与fastIndex之间的间隔节点数是固定的所以当fastIndex指向null的时候slowIndex所指向的位置也就是从fastIndex开始往后数第n+1个节点的位置也就是删除节点的前一个位置这样就可以巧妙的删除节点了。