题目
给你一个链表,删除链表的倒数第 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
解法
/**
* Definition for singly-linked list.
* 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* dummyHead = new ListNode(0);
dummyHead->next = head;
// 快慢指针
ListNode* p = dummyHead;
ListNode* q = dummyHead;
for(int i = 0 ; i < n+1 ; i++)
{
q = q->next;
}
//p和q一起走
while(q)
{
p = p->next;
q = q->next;
}
// 删除p->next
ListNode* delNode;
delNode = p->next;
p->next = delNode->next;
delete delNode;
// 返回结果,删除dummyHead
ListNode *resNode = dummyHead->next;
delete dummyHead;
return resNode;
}
};
};
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
笔记
解题思路:
-
设置虚拟节点 dummyHead 指向 head
-
设定双指针 p 和 q,初始都指向虚拟节点 dummyHead
-
移动 q,直到 p 与 q 之间相隔的元素个数为 n
-
同时移动 p 与 q,直到 q 指向的为 NULL
-
将 p 的下一个节点指向下下个节点
错误写法:
ListNode *p, *q; //双指针,哑结点(dummy node)实现
// 初始都指向head
p = head;
q = head;
int dis = -1; //记录p和q之间间隔的距离
if(! head->next) return nullptr; //特判
while(q != nullptr && dis < n ) //q判空
{
q = q->next;
dis++;
}
//同时移动
while(q != nullptr)
{
p = p->next;
q = q->next;
}
ListNode* delNode;
delNode = p->next;
if(p->next != nullptr){
p->next = delNode->next;
}
delete delNode;
return head;