删除链表的倒数第n各节点难点再入如何找到倒数第n个节点。在不使用额外空间的情况下,可以通过计算或者通过双指针去寻找,这里有俩种方法;第一种 计算,第二种 双指针,效率上第二种比较快


/**
* <p>给你一个链表,删除链表的倒数第 <code>n</code><em> </em>个结点,并且返回链表的头结点。</p>
*
* <p> </p>
*
* <p><strong>示例 1:</strong></p>
* <img alt="" src="https://assets.leetcode.com/uploads/2020/10/03/remove_ex1.jpg" style="width: 542px; height: 222px;" />
* <pre>
* <strong>输入:</strong>head = [1,2,3,4,5], n = 2
* <strong>输出:</strong>[1,2,3,5]
* </pre>
*
* <p><strong>示例 2:</strong></p>
*
* <pre>
* <strong>输入:</strong>head = [1], n = 1
* <strong>输出:</strong>[]
* </pre>
*
* <p><strong>示例 3:</strong></p>
*
* <pre>
* <strong>输入:</strong>head = [1,2], n = 1
* <strong>输出:</strong>[1]
* </pre>
*
* <p> </p>
*
* <p><strong>提示:</strong></p>
*
* <ul>
* <li>链表中结点的数目为 <code>sz</code></li>
* <li><code>1 <= sz <= 30</code></li>
* <li><code>0 <= Node.val <= 100</code></li>
* <li><code>1 <= n <= sz</code></li>
* </ul>
*
* <p> </p>
*
* <p><strong>进阶:</strong>你能尝试使用一趟扫描实现吗?</p>
* <div><div>Related Topics</div><div><li>链表</li><li>双指针</li></div></div><br><div><li>👍 1953</li><li>👎 0</li></div>
*/

//leetcode submit region begin(Prohibit modification and deletion)

/**
* 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 dummy = new ListNode(0);
dummy.next= head;

ListNode countP = head;
int len =0;
while(countP!=null){
len++;
countP=countP.next;
}


System.out.println("len " +len);

int currIndex = 0;
int removeIndex = len+1-n-1;
System.out.println("removeIndex " +removeIndex);

ListNode curr = dummy;
while(curr!=null){
if(currIndex==removeIndex){
curr.next=curr.next.next;
return dummy.next;
}else{
currIndex++;
curr=curr.next;
}
}
return dummy.next;
}
}
//leetcode submit region end(Prohibit modification and deletion)


/**
* 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 dummy = new ListNode(-1);
dummy.next=head;
ListNode p = findFromEnd(dummy,n+1);
p.next=p.next.next;
return dummy.next;
}

/**
* 5个节点,倒数第三个既第2个节点;要删除2就要找到第1个节点
* 5-3=2,传入的虚拟节点既 6-3 = 3;是原先链表的第二节点
*
* @param head
* @param k
* @return
*/
ListNode findFromEnd(ListNode head,int k){
ListNode p1=head;
for (int i = 0; i < k; i++) {
p1=p1.next;
}

ListNode p2=head;
while(p1!=null){
p1=p1.next;
p2=p2.next;
}
return p2;
}
}