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

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




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值