题目描述:
方法一:这是我最开始想到的方法,简答直接。先找到链表的长度count,然后删除第count-n+1个节点。需要两遍遍历。复杂度为o(n),n为链表的长度。
代码:
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* find = head;
long count = 1;
while (find->next != NULL)
{
++count;
find = find->next;
}
ListNode *curr = head;
ListNode *pre = NULL;
for (int i = 1; i <= count - n; ++i)
{
pre = curr;
curr = curr->next;
}
if (curr == head)
head = curr->next;
else
pre->next = curr->next;
delete curr;
return head;
}
};
方法二:方法一的复杂度为o(n),已经是最优的复杂度,因为链表的操作只能通过头一步步到达某个节点,就好像逐个比较法一样。但是,还可以改进,使用两个指针同时遍历,保持前后指针距离为n个节点,遍历一次,就可完成任务,使计算量大概下降一半。
代码:
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode *first = head;
ListNode *second = head;
long count = 0;
while (first->next != NULL)
{
++count;
first = first->next;
if (count > n)
second = second->next;
}
if (count < n)
{
head = head->next;
delete second;
}
else
{
first = second->next;
second->next = second->next->next;
delete first;
}
return head;
}
};