#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)



浙公网安备 33010602011771号