嘿,各位技术潮人!好久不见甚是想念。生活就像一场奇妙冒险,而编程就是那把超酷的万能钥匙。此刻,阳光洒在键盘上,灵感在指尖跳跃,让我们抛开一切束缚,给平淡日子加点料,注入满满的passion。准备好和我一起冲进代码的奇幻宇宙了吗?Let's go!
我的博客:yuanManGan
目录
题目来源力扣1089复写零
题目理解
有一个数组arr当出现0元素时复制一个0在后面并且将后面元素向后移动,但数组的长度不变。
题目还是要求就地移除。
思路讲解
方法一暴力求解
我们之前学习过的vector,可以使用里面的insert内置函数来解决,当元素为0时就在其后面插入一个零,但要求数组的元素个数不变,我们可以先记录没开始遍历时的元素个数,然后遍历数组之后进行尾删操作,即可。这个很好理解,但不是最优秀解。
方法二异地复写
如果没有要求就地移除,我们就可以采取异地复写操作,定义cur指针来遍历数组,dest指针来存储元素在新数组中当dest = n - 1时遍历结束。最后再拷贝回去就ok了。
最后结果
方法三双指针
如果我们定义的两个指针都指向前面的元素从前往后去遍历,遇到0就改两个,你就会发现我们会把还未遍历的元素修改了所以我们得从后往前遍历。
那问题来了cur和dest应该指向什么位置呢,dest不难像肯定是最后一个元素,curne?cur是不是改指向最后要修改的位置及看方法二中cur最后指向的位置。怎么找到这个位置我们先不管,我们先来实现一下找到了这个位置后的复写操作:
当cur指向的位置不是0时,直接把dest位置的值改成cur的值,然后统一移动一位。
而cur指向的位置是0时,将dest的值改成0,移动一位,再改成0 然后curdest移动一位。
接下来我们讲讲怎么找到cur指向的位置。
我们先让cur指向第一个元素,dest指向-1。
然后进行以下操作:
1.先判断cur是否为0。
2.根据cur的值判断dest移动一步还是两步。
3.判断dest有没有到达最后位置。
4.cur++;
但是还是存在特殊情况:当arr为[ 1, 0, 2, 3, 0, 4 ]时
dest就会发生越界,再力扣上会报错,那我们改怎么解决呢?当发生这种情况时一定是cur指向了0,我们只需要将n-1位置上的数修改成0再将dest移动两位,cur移动一位即可。
然后继续进行操作即可。
代码实现
方法一
分析复杂度 : 时间复杂度for循环 n 内层insert n while循环 忽略 所以 时间复杂度为O(n^2).
空间复杂度O(1)。
方法二
分析复杂度 : 时间复杂度for循环 n 内层可以忽略 所以 时间复杂度为O(n).
空间复杂度O(n), 因为创建了新数组。
方法三
分析复杂度 : 时间复杂度几个while循环都是n所以 时间复杂度为O(n).
空间复杂度O(1)。