给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode* removeNthFromEnd(ListNode* head, int n){}
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
一趟遍历
删除一个节点,你需要知道其前面的节点,因此这里添加了一个头节点。让q指针先移动n-1步,随后pre p q三个指针一起移动。等到q移动到最后一个节点,p指向的就是要删除的节点。这里还需要特判一下是不是删除的头节点。方法就是判断pre有没有移动。
#include<iostream>
using namespace std;
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode* removeNthFromEnd(ListNode* head, int n)
{
ListNode* pre = new ListNode(-1);
ListNode* pre_temp = pre;//为了判断pre是不是没动,是不是删除的是头节点
pre->next = head;//删除节点需要知道其前面的指针
ListNode* p = head;
ListNode* q = head;
for (int i = 1; i <= n - 1; i++)//只需要移动n-1次
{
q = q->next;
}
while (q->next != NULL)
{
pre = p;
p = p->next;
q = q->next;
}
pre->next = p->next;
if (pre == pre_temp)
{
return pre->next;
}
else
{
return head;
}
}
int main()
{
int i;
ListNode* head = new ListNode(-1);
ListNode* p = head;
while (cin >> i)
{
ListNode* temp = new ListNode(i);
p->next = temp;
p = temp;
}
ListNode* result = removeNthFromEnd(head->next, 5);
while (result != NULL)
{
cout << result->val << "->";
result = result->next;
}
}
AC