记录:2021.8.7 链表:删除链表的倒数第N个结点(med)
给你一个链表,删除链表的倒数第 n 个结点,
进阶:你能尝试使用一趟扫描实现吗?
示例 1:
输入:head = [1,2,3,4,5],
输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1
输出:[]
示例 3:
输入:head = [1,2], n = 1
输出:[1]
提示:
链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
Related Topics 链表 双指针
思路1:
链表计数(没有使用添加哑结点的方法: ListNode dummy = new ListNode(0, head); )
先遍历一遍链表获取链表长度,然后再遍历到size-n-1,即遍历到了倒数第n+1。例如1,2,3,4,5,n=2;
先for(i=0;i<(5-2-1)=2;i++){head=head.next},head就走到了3的位置,而我们要删除的是倒数第n个数,也就是4,所以head.next=head.next.next即可。
需要注意的是,这种方法因为没有使用哑结点,所以当只有一个数和要删除头结点的时候,需要特判:
if(size==1){return null}和if(size==n){head=head.next;return result.next}。
删除头结点时,直接把head指向它的下一结点,然后返回第二个结点的地址即可。
代码:
/**
* 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 node=head;
ListNode result=head;
int size=0;
while(node!=null){
size++;
node=node.next;
}
if(size==1){
return null;
}
for (int i = 0; i < size-n-1; i++) {
head=head.next;
}
if(n==size){
head=head.next;
return result.next;
}
head.next=head.next.next;
return result;
}
}
思路2:
使用哑结点和双指针(快慢指针)。快指针先走n个结点,然后慢指针开始走
所以它们之间固定相差n个结点,当快指针走到链表尾的时候,慢指针的位置即为倒数第n个结点
直接left.next=left.next.next即可。
注:慢结点需要构造哑结点
代码:
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode result=new ListNode(0,head);
ListNode left=result;
ListNode right=head;
for (int i = 0; i < n; i++) {
right=right.next;
}
while(right!=null){
left=left.next;
right=right.next;
}
left.next=left.next.next;
return result.next;
}
}