leetcode 19. 删除链表的倒数第 N 个结点
删除链表的倒数第 N 个结点
题目描述
给你一个链表,删除链表的倒数第 n
个结点,并返回链表的头结点。
解题思路
为了删除倒数第 n
个节点,我们可以使用双指针法。首先,我们将第一个指针 first
移动到链表的第 n+1
个节点,然后将第二个指针 second
移动到链表的开头。接着,我们同时移动 first
和 second
直到 first
指向链表的末尾。此时,second
就是倒数第 n
个节点的前一个节点,我们可以修改指针进行删除操作。
最初解法
java
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummyHead = new ListNode(-1, head);
int length = getLength(head);
ListNode cur = dummyHead;
for(int i = 0; i < length - n - 1; i++) {
cur = cur.next;
}
cur.next = cur.next.next;
return dummyHead.next;
}
private int getLength(ListNode head) {
int length = 0;
while(head != null) {
length++;
head = head.next;
}
return length;
}
}
最初解法思路:
- 使用
getLength
方法获取链表长度。 - 使用
dummyHead
辅助节点,然后找到倒数第n
个节点的前一个节点进行删除。
问题:
- 需要遍历两次链表,效率相对较低。
优化解法
java
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummyHead = new ListNode(-1, head);
ListNode first = head;
ListNode second = dummyHead;
for(int i = 0; i < n; i++) {
first = first.next;
}
while(first != null) {
first = first.next;
second = second.next;
}
second.next = second.next.next;
return dummyHead.next;
}
}
优化解法思路:
- 使用双指针
first
和second
,它们之间的距离是n+1
。 - 移动
first
指针到链表末尾,second
指针就会指向倒数第n
个节点的前一个节点。
优点:
- 一次遍历解决问题,提高了效率。
复杂度分析
最初解法:
- 时间复杂度:O(N)(遍历两次链表)
- 空间复杂度:O(1)(只使用了常数额外空间)
优化解法:
- 时间复杂度:O(N)(遍历一次链表)
- 空间复杂度:O(1)(只使用了常数额外空间)