leetcode挨个儿刷150105(2):Remove Nth Node From End of List

来源:互联网 发布:淘宝店铺被扣了48分 编辑:程序博客网 时间:2024/05/19 00:11

这个题做完了不仅对自己的粗心表示深深地痛心,这么简单的一道题,还提交了几次,就因为自己脑卡了,起初把结点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;   }};




0 0