力扣-283-移动0
要求在原地对数组进行操作
常规思路:
- 找到(匹配)0
- 移动0到数组末尾
难点应该在“移动0到末尾”这个步骤上,如果用交换,那么效率是很低的,如果每一个0都要交换一轮,那效率是奇低的
但是我们可以换一个思路,不要想着去移动0,而是去移动非0
双指针
- 指针1用于遍历数组,指针2用于指向第一个(最左边的)0
- 指针1初始值为0,指针2初始值也为1
指针1遍历数组,当遇到一个非0的元素时,将指针1指向的元素与指针2指向的元素交换
当遇到一个0时,检查……好像不太对
我又有一个想法(手动滑稽)
它只要求保持非零元素的相对顺序,零元素相对位置没有区别,也就是所有的0都完全没区别
那么,我为什么要傻不拉几地去移动0?我自己补不行吗
还是上面地双指针,让两个指针中间夹的部分都是0元素
只要把非0元素全部往数组前面搬,最后我补0就行
解题思路
整理一下
初始化指针1=0,指针2=-1
扫描到0元素,1指针不操作,继续往下走,2指针检查指向是否为0,是就不动,不是就重新指向当前位置
扫描到非0元素,检查2指向是否为0,是就把当前值赋值过去,当前置0
判0
这里考虑能不能用位操作来实现,有两个思路
- 用与运算&1(好吧,这个只能用来判奇偶)
- 用异或
好吧,好像都不太行,去网上查了一圈,判0好像用位运算也不合适
第一版
class Solution { public: void moveZeroes(vector<int>& nums) { int point1,point2=0; for(point1=0;point1<nums.size();++point1){ if(nums[point1]==0){ if(nums[point2]!=0){ point2 = point1; } }else{ if(nums[point2]==0){ nums[point2] = nums[point1]; nums[point1] =0; point2++; } } } } };
虽然写出来了,但我好像还没有完全搞明白为什么这样写是正确的
一看就只有两个判断,当遇到0的时候,如果point2不为0,就更新point2
当不为零,如果point2指向0,就将当前值赋过去然后置零,更新point2……直接自加……?
我感觉自加不合适,但是删了直接报错
自加,应该只是为了让point2往后走一位,更新一步,但是保证更新后的值一定是什么吗?反正不更新的话指向一定不为0
往前走一步,如果point2+1=point1,那么一定是0,如果point1和point2之间还有元素…如果他俩之间还能有元素,那么一定是point2没更新,point1向下走,也就是函数体没有执行
- point1指向0,但此时point2也指向0
- point1指向非零,此时point2也指向非0
有没有可能point1指向不为0,此时point2指向也不为0,那么会怎么样?有没有这种可能
例如,第一个元素就不为0,那么point2还是0,point1直接下一个,相当于什么操作都不做
本文作者:YaosGHC
本文链接:https://www.cnblogs.com/yaocy/p/16343961.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步