19 删除链表的倒数第 N 个结点
题目
给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
**进阶:**你能尝试使用一趟扫描实现吗?
示例 1:
输入: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
解决方案一
方遍历链表查询链表长度,然后第二次查找删除结点的位置,删除结点返回删除后的链表。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
if(!head) return nullptr;
ListNode new_node(-1);
new_node.next = head;
ListNode* new_head = &new_node;
ListNode* p = new_head;
int length = 0;
while(p->next) {length++; p = p->next;}
p = new_head;
int i = 0;
while(p->next && length - i > n){
p = p->next;
++i;
}
ListNode* temp = p->next;
p->next = p->next->next;
delete temp;
return new_head->next;
}
};
方案一效果:
208/208 cases passed (4 ms)
Your runtime beats 83.94 % of cpp submissions
Your memory usage beats 76.96 % of cpp submissions (10.3 MB)
解决方案二(参考他人)
利用双指针,两个指针相差n
个结点,当快指针达到最后一个元素时,慢指针指向倒数第n
个元素。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
if(!head) return nullptr;
ListNode new_head(-1);
new_head.next = head;
ListNode *fast = &new_head, *slow = &new_head;
for(int i = 0; i < n; i++){
fast = fast->next;
}
while(fast->next){
fast = fast->next;
slow = slow->next;
}
ListNode *temp = slow->next;
slow->next = slow->next->next;
delete temp;
return new_head.next;
}
};
方案二效果:
208/208 cases passed (0 ms)
Your runtime beats 100 % of cpp submissions
Your memory usage beats 26.99 % of cpp submissions (10.5 MB)