题目链接
Remove Nth Node From End of List - LeetCode
注意点
- 考虑删除的结点是开头的那个结点
- 输入给的链表是没有开头的"哑结点"的
解法
解法一:先在开头加一个哑结点,这样可以简化后面的处理。一次遍历统计有多少个结点。然后再一次遍历找到倒数第n个结点,修改next指针,结束循环。时间复杂度为O(n)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* ans = new ListNode(0);
ans->next = head;
ListNode* p = ans;
ListNode* q = ans->next;
int count = 0;
while(q != NULL)
{
q = q->next;
count++;
}
int stop = count-n+1;
count = 1;
q = ans->next;
while(q != NULL)
{
if(count == stop)
{
p->next = q->next;
break;
}
p = q;
q = q->next;
count++;
}
return ans->next;
}
};
解法二:只需要一次遍历,两个指针p和q,首先p先走n步,然后p和q一起走,当p走到结尾的时候q就走到倒数n+1个结点了。时间复杂度为O(n)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* p = head;
ListNode* q = head;
while(n > 0)
{
p = p->next;
n--;
}
if(p == NULL)//remove first node
{
return q->next;
}
while(p->next != NULL)
{
q = q->next;
p = p->next;
}
q->next = q->next->next;
return head;
}
};
小结
- 解法二还是很精妙滴