文章目录
- 一、题目
- 二、双指针法
- 三、完整代码
所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。
一、题目
二、双指针法
思路分析:这道题使用双指针一次遍历就能删除目标节点。快慢指针同一位置出发(虚节点),先让快指针前进n步,然后快慢指针一起更新,等到快指针到达链表末尾NULL指针时,慢指针指向倒数第n个节点,然后做删除操作。要注意快指针指向NULL时,慢指针要指向删除节点的上一个节点,因此要让快指针多走一步。
程序如下:
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* FakeNode = new ListNode(0, head);
ListNode* Fastptr = FakeNode;
ListNode* Slowptr = FakeNode;
// 快慢指针确定相对位置
while (n-- && Fastptr->next != NULL) Fastptr = Fastptr->next;
Fastptr = Fastptr->next; // 需要让fast指针再往前一步
// 移动快慢指针,找到删除节点
while (Fastptr != NULL) {
Slowptr = Slowptr->next;
Fastptr = Fastptr->next;
}
// 删除节点
ListNode* tmp = Slowptr->next; // 要删除的节点
Slowptr->next = tmp->next;
delete tmp; // 手动释放内存
return FakeNode->next; // 返回头结点
}
};
复杂度分析:
- 时间复杂度: O ( n ) O(n) O(n)。
- 空间复杂度: O ( 1 ) O(1) O(1)。
三、完整代码
# include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode* next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode* next) : val(x), next(next) {}
};
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* FakeNode = new ListNode(0, head);
ListNode* Fastptr = FakeNode;
ListNode* Slowptr = FakeNode;
// 快慢指针确定相对位置
while (n-- && Fastptr->next != NULL) Fastptr = Fastptr->next;
Fastptr = Fastptr->next; // 需要让fast指针再往前一步
// 移动快慢指针,找到删除节点
while (Fastptr != NULL) {
Slowptr = Slowptr->next;
Fastptr = Fastptr->next;
}
// 删除节点
ListNode* tmp = Slowptr->next; // 要删除的节点
Slowptr->next = tmp->next;
delete tmp; // 手动释放内存
return FakeNode->next; // 返回头结点
}
};
ListNode* ChainGenerator(int arr[], int len) {
ListNode* head = new ListNode(arr[0], NULL);
ListNode* p = head;
for (int i = 1; i < len; i++) {
ListNode* pNewNode = new ListNode(arr[i], NULL);
p->next = pNewNode; // 上一个节点指向这个新建立的节点
p = pNewNode; // p节点指向这个新的节点
}
return head;
}
void my_print(ListNode* head, string str) {
cout << str << endl;
ListNode* cur = head;
while (cur != NULL) {
cout << cur->val << ' ';
if (cur->next == NULL) break;
cur = cur->next;
}
cout << endl;
}
int main()
{
//int arr[] = { 1,2,3,4,5 };
//int IndexFromEnd = 2;
int arr[] = { 1 };
int IndexFromEnd = 1;
int len = sizeof(arr) / sizeof(int);
Solution s1;
ListNode* head = ChainGenerator(arr, len);
my_print(head, "目标链表:");
head = s1.removeNthFromEnd(head, IndexFromEnd);
my_print(head, "删除目标元素后的链表:");
system("pause");
return 0;
}
end