持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情
一、题目
struct ListNode {
int val;
ListNode *next = nullptr;
inline ListNode(int x, ListNode* next = nullptr) : val(x), next(next) { }
};
ListNode* removeReverseNode(ListNode* pHead, int n) {
}
int main(int, char**)
{
ListNode p1(1);
ListNode p2(2);
ListNode p3(3);
ListNode p4(4);
ListNode p5(5);
p1.next = &p2;
p2.next = &p3;
p3.next = &p4;
p4.next = &p5;
p5.next = nullptr;
ListNode* node = removeReverseNode(&p1, 2);
cout << node->val << endl;
return 0;
}
二、分析
根据题意可知
难点一:
需要获取倒数第n个节点
因为是单向链表,所以不能直接从右往左数,
此时就需要有两个节点,一个节点先跑n步,
然后两个节点同时一步一步的跑,跑得快的节点跑到终点,
此时跑得慢的节点就刚好指向需要的节点。
由于是单向链表,删除节点又需要此节点的父节点,
所以在两个节点一起跑的时候还得记录跑得慢的父节点。
三、模拟
-
创建两个遍历节点
节点一 跑得快A
节点二 跑得慢B -
跑得快先跑
n减一
跑得快A 走一步
只要n不等于0就继续 -
两个节点一起跑
跑的快A 走一步
跑得慢B 走一步
只要跑的快A没到终点就继续 -
删除节点
四、实现
ListNode* removeReverseNode(ListNode* pHead, int n) {
ListNode* rabbit = pHead;
ListNode* tortoise = pHead;
ListNode* tortoiseParent = nullptr;
while(n){
--n;
rabbit = rabbit->next;
}
while(rabbit){
rabbit = rabbit->next;
tortoiseParent = tortoise;
tortoise = tortoise->next;
}
if(tortoiseParent){
tortoiseParent->next = tortoise->next;
}
return tortoise;
}
五、结言
利用操场跑步原理,解题的思路就很明显了,而关键的点就在于如何获取倒数的节点,我们通过生活中平移测距的方法来解决问题,这道题就变得非常简答了
创作不易,留个赞再走吧!如果对文章内容有任何指正,欢迎评论!