#Leetcode27

不知道是不是我的理解能力有问题,有时看题目都要看半天,是我看书不够多的原因吗?写这道题前后花了一个多小时,我昨天思考了一阵子:有太多的优秀的人了,他们怎么可以懂那么多,他们为什么可以去大公司上班?他们为什么这么优秀?他们为什么可以达到在我看来是如此高的成就?我为什么就没有他们这样的才华?我要怎么去做才能像他们那样?后来想明白了,他们都是慢慢变化的,我不相信他们一开始就那么强的?有谁一开始就那么优秀的呢?我又想到别人健身,为什么他就可以把肌肉练得那么大块?而我却不行,把以上现象抽象出来,我发现:首先是要有变优秀的决心,然后要有科学的训练方法,接着就是持之以恒,慢慢去做,要有耐心,不要急,不要和其他人比,和他人比较没啥意义,很耗费一个人的能量的,要和昨天的自己比,哪怕比昨天的自己好一点,日积月累,不要小看这一点点,时间的力量很强大,小和大都是相对的,一切都是相对的,慢慢去做,想不到做什么事情就刷题,写总结,题要反复刷,刷过的也可以刷,真的深有体会,别人告诉你方法了和路了,你就是迟迟不去做,等啥?一开始是很难受的,但要忍着,这是你进步的机会,你要相信,没有啥是永恒和绝对的,某种状态也不会持续多久的,难受一会就好了,我的缺点就是等所有的东西都准备好了才开始做,那就大可不必,我现在还是该不了这个习惯,就像搜集资源,我不停的在收集资源,成瘾了,我要是刷题能成瘾该多好,我相信我是可以做到的,你搜集那么多资源为什么?你要变搜集边学啊,要有危机意识,万一哪天电脑坏了,或者被偷了,所有的资源都化为乌有了,那些用来搜集资源的时间也就沉没了,前段时间看书上说:书看完后,你吸收了对你有用的知识后,这书就可以扔掉了,英语的语法也是,语法就是为了让你看懂英文句子的,既然看懂句子了,就不必每次看句子时就分析语法,一切的一切都是为了训练你的大脑,你的能力,这点要清楚,能力至上,我的近期愿望就是能刷题上瘾和考试顺利!

又跑远了,废了那么多话,回归正题。

LeetCode27题目

 

 

 有三种解法,先看最直接,最暴力的

 1 class Solution {
 2 public:
 3     int removeElement(vector<int>& nums, int val) {
 4         int size = nums.size();
 5         for (int i = 0; i != size; ++i)
 6         {
 7             if (nums[i] == val)
 8             {
 9                 for (int j = i + 1; j != size; ++j)
10                 {
11                     nums[j - 1] = nums[j];
12                 }
13                 size--;//我写的错误提交二:13,14 行放在if块的外面了,错误的原因是如果没有匹配到要删除的元素,这个也会执行就是错的
14                 i--;
15             }
16         }
17         return size;
18     }//我写的错误提交一:nums.size()--;
19 };

这个还是很明确的,就是发现目标就用后面的元素来覆盖掉它,然后数组的长度更新,那为什么i也要更新呢?i的位置是目标删除元素的位置,它被后面一位给覆盖了,那后面一位是不是也是目标删除元素呢?所以就要退回一格来检查一下,这种解法的时间复杂度为O(n ^ 2)

那我们来看看第二种解法:双指针法

 1 class Solution {
 2 public:
 3     int removeElement(vector<int>& nums, int val) {
 4         int slowindex = 0;
 5         for (int fastindex = 0; fastindex != nums.size(); ++fastindex)
 6         {
 7             if (nums[fastindex] != val)
 8                 nums[slowindex++] = nums[fastindex];
 9         }
10         return slowindex;
11     }
12 };

这个时间复杂度为O(n),巧妙之处在于如果找到了目标元素,那快指针就比满指针要快了,如果一直没有发现目标,那慢指针和快指针就是平起平坐啦

前面两种方法都是用C++来实现的,最后一种我用的是C(大佬建议刷题要么用C++,要么用Java,别用C,避免重新创轮子),我其实是看了hao题解后写的,非常amazing

 1 int removeElement(int* nums, int numsSize, int val){
 2     int i = 0;
 3     numsSize -= 1;
 4     while (i <= numsSize)
 5     {
 6         if (nums[i] == val)
 7         {
 8             nums[i] = nums[numsSize--];
 9             continue;
10         }
11         ++i;
12     }
13     return numsSize + 1;
14 }

这种解法的妙处在于避免了多次不必要的赋值操作,而且也很好的利用了题目的条件,就是删除元素后数组里的元素顺序随意

好了,这一早就忙活了一道题和写了博文

 

-------------------------------------------------------------------------------------------------------------------

今天是双十二,距离第一次刷这题有一定时间了,我看了吴师兄的公众号后,发现这道题的另外一种实现方法,就是看起来没那么复杂

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int size = 0;
        for(int i:nums)
        {
            if(i != val)
            {
                nums[size++] = i;
            }
        }
        return size;
    }
};

早上还特意去看了C++11的for each循环,然后就找hj的视频,没发现,后来就看了stl的vertor,动态数组的源码那节课,还可以,学了数据结构再去看,没那么吃力,后来还看了auto关键字

 

---------------------------------------------------------------------------------------------------------------------

今天是2022.1.16的下午

我先是想写26题的,然后就是呆在哪里了,不知道如何写,我看了我之前的提交记录,也挺波折的,然后就转回写27题找找感觉,也写了很久,我一开始就想用haoel的方法写,但没写出来,他用C实现看起来很amazing的方法,我犯了一个错误,就是在想”答案“,而不是想思路。

 

 

 看到官方的解答

 

 

 

 java实现的代码

 

 时间复杂度O(n)

 空间复杂度O(1)

 

 

 

 

 

posted @ 2021-11-28 11:06  越菜越自信  阅读(35)  评论(2)    收藏  举报