链表的数据结构
//Definition for singly - linked list.
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
方法一:遍历节点时用一个栈存储节点。然后pop出N个节点,最后pop的节点为需要被删除的节点。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
stack<ListNode*> s;
ListNode* temp = head;
while (temp)
{
s.push(temp);
temp = temp->next;
}
while (n > 1)
{
s.pop();
n--;
}
ListNode* eraseNode = s.top();//被删除的节点
s.pop();
if (eraseNode != head)//被删除节点不是头节点
{
ListNode* last = s.top();
last->next = eraseNode->next;
}
else//被删除的节点是头节点
{
head = eraseNode->next;
}
return head;
}
};
方法二:双指针。先让first指针移动n+1次(即指向第n+1个节点),然后first和second一起向后移动,此时first和second指针中间必然间隔n个节点。若不是删除头节点时,当first指针移动到链表末尾时,second指针指向被删除节点的前一个节点。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* first=head;//算作第一次移动
ListNode* second=head;
for (int i = 1; i <= n; i++)//第一个指针移动n+1个位置
{
first = first->next;
}
if (first == nullptr)//删除头节点
{
return head->next;
}
while (first->next)
{
first = first->next;
second = second->next;
}
ListNode* eraseNode = second->next;
second->next = eraseNode->next;
return head;
}
};