力扣-283-移动0

要求在原地对数组进行操作

常规思路:

  1. 找到(匹配)0
  2. 移动0到数组末尾

难点应该在“移动0到末尾”这个步骤上,如果用交换,那么效率是很低的,如果每一个0都要交换一轮,那效率是奇低的

但是我们可以换一个思路,不要想着去移动0,而是去移动非0

双指针

  1. 指针1用于遍历数组,指针2用于指向第一个(最左边的)0
  2. 指针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. 用与运算&1(好吧,这个只能用来判奇偶)
  2. 用异或
    好吧,好像都不太行,去网上查了一圈,判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向下走,也就是函数体没有执行

  1. point1指向0,但此时point2也指向0
  2. point1指向非零,此时point2也指向非0

有没有可能point1指向不为0,此时point2指向也不为0,那么会怎么样?有没有这种可能

例如,第一个元素就不为0,那么point2还是0,point1直接下一个,相当于什么操作都不做

本文作者:YaosGHC

本文链接:https://www.cnblogs.com/yaocy/p/16343961.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   YaosGHC  阅读(27)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起