19 删除链表的倒数第 N 个结点

题目

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

示例 1:

img

输入:head = [1,2,3,4,5], n = 2
输出:[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

思路

第一个思路就是,先遍历一遍,找到size,然后倒数k个节点就是size - k + 1,因为我们要移除这个节点,所以我们遍历到size-k的时候就可以,

时间负责度O(n)

第二个思路,我们快指针遍历k-1次,然后快慢指针同时遍历,当快指针遍历到末尾的时候,慢指针的指向的节点就是要移除的节点

实现

遍历一遍找到size

需要考虑移除头节点的情况,这里我是用一个if判断,是否移除头节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
private static class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode myHead = head, iterHead = head;
int size = 0;
while (myHead != null) {
size++;
myHead = myHead.next;
}
// 移除头节点
if (size == n) {
// 如果及一个节点,返回kong
if (iterHead.next == null) {
return null;
} else {
// 否则返回下一个节点
iterHead = iterHead.next;
return iterHead;
}

}
for (int i = 0; i < size - n - 1; i++) {
iterHead = iterHead.next;
}
iterHead.next = iterHead.next == null ? null : iterHead.next.next;
return head;
}
}

上面移除头节点的代码比较冗余,我们可以可以虚拟机一个头节点,这样就不用考虑是否移除头节点的问题