问题描述
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
方法一:
思路
1.遍历链表求出链表的长度。
2.遍历链表删除指定节点。
3.注意删除头节点的情况
AC代码
/**
* 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) {
int k = 0;
for (ListNode *p = head; p; p = p->next)
k ++;
if (k == 1) return nullptr;
if (k == n) return head->next;
k -= n;
int a = 0;
for (auto p = head; p; p = p->next) {
++ a;
if (a == k)
p->next = p->next->next;
}
return head;
}
};
方法二:
思路
定义一个虚拟头结点,就可以避免删除头节点的情况了
AC代码
/**
* 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) {
auto dummy = new ListNode(-1);
dummy->next = head;
int k = 0;
for (auto p = dummy; p; p = p->next) k ++;
auto p = dummy;
for (int i = 0; i < k - n - 1; i ++) p = p->next;
p->next = p->next->next;
return dummy->next;
}
};