这个题做完了不仅对自己的粗心表示深深地痛心,这么简单的一道题,还提交了几次,就因为自己脑卡了,起初把结点p作为head结点的前一个节点,后面在统计结点个数的时候,居然把它当做自由结点,移动了,怪不得结果一直不对呢。
忽然想起了很久很久以前,听一个学长分享自己的代码刷题经验的时候说道,我们在写程序时,一定要想好了,什么是可以改变的,什么是不能变的,再去写,不要匆匆忙忙,不然调试将是一件非常痛苦的事情。看见了吧,今天就尝了苦果。还好年轻,还有时间改,要警惕呀,lisa同学!加油!
No2:https://oj.leetcode.com/submissions/detail/17948348/
Given a linked list, remove the nth node from the end of list and return its head.
For example,
Given linked list: 1->2->3->4->5, and n = 2. After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
Try to do this in one pass.
/**
* Definition for singly-linked list.
*/
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
ListNode *removeNthFromEnd(ListNode *head, int n) {
if(head == NULL)
return NULL;
ListNode *p=new ListNode(0);
ListNode *q;
p ->next = head;
q=p;
int count=0;
while(q ->next != NULL)
{
count ++;
q = q->next;
}
//cout<<count<<endl;
//判断n的合理范围
if( (n <= 0) ||(n > count) )
return NULL;
//如果删除到头结点
if(n == count)
{
q = head;
p->next = q->next;
delete q;
head = p->next;
return head;
}
//删除非头结点的其余结点
p = head;
q = head->next;
for(int i=1;i<count-n;i++)
{
p=p->next;
q=q->next;
}
p->next=q->next;
// cout<<endl<<q->val<<endl;
delete q;
return head;
}
};
程序的测试部分:
int main()
{
ListNode * l1= new ListNode(2);
ListNode *p=l1;
for(int i = 1; i <= 4; i++)
{
ListNode *newnode=new ListNode(i);
p->next=newnode;
p=newnode;
cout<<p->val<<" ";
}
Solution s;
l1 = s.removeNthFromEnd(l1,2);
ListNode *q=l1;
cout<<endl<<"* "<<endl;
for(;q!=NULL;q=q->next)
cout<<q->val;
cout<<"* "<<endl;
return 0;
}
分析程序,其时间复杂度是:O(n),因为为p申请了内存,空间复杂度为O(1)。
在网站上得到的运行时间图为:
时间属于较短的范围,可以接受。
范例代码的思路很巧妙,它使用了两个指针,一个指针先走n步,然后这两个指针一起走,先走的到了尾巴,其实另一个指针就指着要被删掉的结点。
根据其思路,实现的代码如下:
class Solution {
public:
ListNode *removeNthFromEnd(ListNode *head, int n) {
if(head == NULL)
return NULL;
if(n<=0)
return head;
ListNode * p=head;
ListNode * q=head;
while(n>1)
{
q=q->next;
if(q == NULL)
{
return NULL;
}
n--;
}
if(q->next==NULL)
{
ListNode * Head=new ListNode(0);
Head->next=head->next;
delete head;
return Head->next;
}
while(q->next->next!=NULL)
{
p=p->next;
q=q->next;
}
q=p->next;
p->next=q->next;
delete q;
return head;
}
};
时间复杂度为O(n),空间复杂度为O(1)。
这一次提交后的时间是
示例代码原版为:
// LeetCode, Remove Nth Node From End of List
// 时间复杂度 O(n) ,空间复杂度 O(1)
class Solution {
public:
ListNode *removeNthFromEnd(ListNode *head, int n) {
ListNode dummy{-1, head};
ListNode *p = &dummy, *q = &dummy;
for (int i = 0; i < n; i++) // q 先走 n 步
q = q->next;
while(q->next) { // 一起走
p = p->next;
q = q->next;
}
ListNode *tmp = p->next;
p->next = p->next->next;
delete tmp;
return dummy.next;
}
};