【leetcode-19】删除链表的倒数第N个结点

 
易错点:


using namespace std;
#include <iostream>

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* fast = head;
ListNode* slow = new ListNode(0, head);
cout << "fast aka head's address: "<<fast << endl;
cout << "slow next address: "<<slow->next << endl;
for (int i = 0; i < n; ++i) {
fast = fast->next;
cout <<"fast address after moving n steps: " <<fast << endl;
}
while (fast) {
fast = fast->next;
slow = slow->next;
}
if (slow->next != nullptr) {
slow->next = slow->next->next;
cout << "slow next address after delete the target node: "<<slow->next << endl;
}
cout << "head address after delete the target node: "<<head << endl;
return head;
}
};

int main()
{
ListNode head = ListNode(1);
Solution s;
s.removeNthFromEnd(&head, 1);
}

 

运行结果(请原谅我的塑料英语哈哈哈,正在努力养成英文注释的习惯中~):

  一般在链表的问题中,使用双指针解法需要设置一个哑结点指向链表头。该解法的错误用例为示例2,当完成结点的删除后,slow->next指向新的”链表头“也即地址00000000,而原先的头结点head仍然指向原地址00FCFBFC,所以此时返回的并不是链表头。

正确解法:

 



using namespace std;
#include <iostream>
#include <vector>
#include <unordered_map>
#include<string>


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* pre = new ListNode(0, head);
cout << "pre's address: " << pre << endl;
ListNode* fast = head;
cout << "fast/head's address: " << fast << endl;
ListNode* slow = pre;
cout << "slow's address: " << slow << endl;
for (int i = 0; i < n; ++i) {
fast = fast->next;
}
while (fast) {
fast = fast->next;
slow = slow->next;
}
slow->next = slow->next->next;
cout << "slow next's address: " << slow->next << endl;
ListNode* res = pre->next;
cout << "pre's address: " << pre << endl;
cout << "res's address: " << res << endl;
cout << "head's address: " << head << endl;
delete pre;
return res;
}
};


int main()
{
ListNode head = ListNode(1);
Solution s;
s.removeNthFromEnd(&head, 1);
}


 

加入哑结点后,可以保存原先指向头结点的”结点“,也就能保证该”结点“的next始终是我们所想要的链表头。

 

 

 

 
 
posted @ 2022-08-10 01:25    阅读(30)  评论(0)    收藏  举报