leetcode Remove Nth Node From End of List

leetcode Remove Nth Node From End of List

题目: 输入一个数组,要求删除倒数第n个元素,然后返回这个数组。例如,输入数组为1,2,3,4,5,删除倒数第2个,则返回数组1,2,3,4。

题目思路:看到题目的时候,就是按照很正常的思路去想,把整个数组扫一遍,然后再找出倒数第n个元素,再把它删除,但是,细节处理比较多。先看第一次写的代码。

代码:

    ListNode* removeNthFromEnd(ListNode* head, int n) 
    {
        ListNode* te=head;
        int size=0;
        while(te!=NULL)//统计整个数组的长度
        {
            size++;
            te=te->next;
        }
        if(size==0||size==1||n>size)//一些特殊情况的处理
        return NULL;
        if(n==size)
        {
            head=head->next;
            return head;
        }


        te=head;
        for(int i=1;i<=size;i++)//寻找倒数第n个元素
        {

            if(n+i==size)
            {
               if(te->next->next!=NULL)
               {
                   ListNode* temp=te->next;
                   te->next=temp->next;
               }
               else
               {
                   te->next=NULL;
               }
               break;
            }
            te=te->next;
        }
        return head;//得到最后的结果
    }

再思考:题目写完的时候,总感觉特例有点多,为什么一定要扫两遍数组呢?倒数第n个就不可以一次性找出来吗?代码是不是可以更短更优美一点。要删除倒数第n个元素,一个指针是不可能实现的,那我要是再用一个指针呢?用两个指针,倒数第n 个,先让两个指针先相距n个单位,那等到一个指针指到数组的尾部,那么前一个指针的下一个就是我们要删除的元素。这种方法,分析来看虽然也需要两个单独的循环,但是,第二次循环往往是不用把整个数组扫完,所以,从这里来说它比上面那种方法来说相对意义 的得到了一定的优化,看代码。

    ListNode* removeNthFromEnd(ListNode* head, int n) 
    {
        if(head==NULL)
        return NULL;
        ListNode* t1=head;//第一个指针
        ListNode* t2=head;//第二个指针
        for(int i=0;i<n;i++)//使两个指针相距n个距离
        t1=t1->next;
        if(t1==NULL)//表示要删除的是数组的第一个元素
        return head->next;
        while(t1->next!=NULL)//寻找倒数第n个元素
        {
            t1=t1->next;
            t2=t2->next;
        }
        t2->next=t2->next->next;
        return head;
    }

反思: 记得这道题上数据结构课的时候老师说过,但是当时也没有仔细听,现在做到这道题目的时候,才深有感悟,其实很多题,仔细想的话,总会有相对自己第一次想到的方法更巧一些。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值