19. 删除链表的倒数第N个节点
两次遍历
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
/**
* 两次遍历
* 先得到链表的长度,再正向遍历到length - n的位置,也就是待删除节点的前一个节点
*/
ListNode dummyHead = new ListNode(0, head);
ListNode cur = dummyHead.next;
int length = 0;
while (cur != null){
length++;
cur = cur.next;
}
ListNode prev = dummyHead;
for (int i = 0; i < length - n; i++) {
prev = prev.next;
}
prev.next = prev.next.next;
return dummyHead.next;
}
}
/**
* 时间复杂度 O(n)
* 空间复杂度 O(1)
*/
双指针
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
/**
* 一次遍历(双指针)
* fast先右移n + 1步,slow再一起移动,直到fast == null,此时slow指向待删除节点的前一个节点
*/
ListNode dummyHead = new ListNode(-1, head);
ListNode fast = dummyHead;
ListNode slow = dummyHead;
for (int i = 0; i < n + 1; i++) {
fast = fast.next;
}
while (fast != null){
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummyHead.next;
}
}
/**
* 时间复杂度 O(n)
* 空间复杂度 O(1)
*/
https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/