力扣hot100-283移动零(盲人拉屎)

283. 移动零 - 力扣(LeetCode)

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

示例 1:

复制代码
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]

示例 2:

复制代码
输入: nums = [0]
输出: [0]

提示:

  • 1 <= nums.length <= 104

  • -231 <= nums[i] <= 231 - 1

**进阶:**你能尽量减少完成的操作次数吗?

相当于把在不改变所有非零元素的相对顺序的前提下将其移动到数组的最前端。最直观的思路就是遍历数组,遇到非零元素就往前扔。那么新问题来了:扔到哪里?所以就需要再声明一个变量去标记应该扔到哪里。这很像双指针,所以不妨右指针一直往后找非零元素,找到了,就把非零元素扔到左指针所在的位置。一旦左指针所在的位置为非零元素,左指针就要往后移动一位,否则就是占着茅坑不拉屎:因为左指针的用处本来就是标记下一个非零元素应该放到哪里,现在它的位置已经被占了,就应该往后挪。

粗俗地说,右指针是一位盲人,非零元素好比右指针拉的屎,左指针是它的导盲犬,它告诉右指针应该往哪里拉屎。如果一个坑已经被屎填满了,那导盲犬应该移动到下一个空的坑位,这样右指针才能知道它下一次应该把屎拉在哪里。

需要注意的是,覆盖和交换略有差别。如果是覆盖,那么最终就要再从左指针left的位置开始,往后面遍历直到数组末尾,将这中间遇到的所有元素都赋值为0.因为没有交换。之所以是从left开始,不是left+1或left-1,是因为left本来就是标记下一个非零元素应该扔到哪里,而最后非零元素一定都被扔到left前面了,所以left开始后面的茅坑必须不能被屎填满。如果遇到了全部为0的数组,那么对于覆盖就要遍历两次数组。但交换的话就不需要考虑这个。

Java:

java 复制代码
class Solution {
    public void moveZeroes(int[] nums) {
        //右指针一直往后移,遇到非零元素,就往前扔
        //具体扔到哪里,由左指针控制。扔到左指针所在的位置
        int left=0,right=0,n=nums.length;
        while(right<n) {
            if(nums[right] != 0) {
                //交换
                int temp = nums[left];
                nums[left] = nums[right];
                nums[right] = temp;
                left++;
            }
            right++;
        }
        //如果是覆盖,那么对于一个全部为0的数组,要遍历两次
    }
}

Go:

Go 复制代码
func moveZeroes(nums []int)  {
    left,right,n := 0,0,len(nums)
    for right < n {
        if nums[right] != 0 {
            temp := nums[left] 
            nums[left] = nums[right]
            nums[right] = temp
            left++
        }
        right++
    }
}

C++:

cpp 复制代码
class Solution
{
public:
    void moveZeroes(vector<int>& nums)
    {
        int n = nums.size();
        int left = 0, right = 0;
        while (right < n)
        {
            if (nums[right])
            {
                swap(nums[left], nums[right]);
                left++;
            }
            right++;
        }
    }
};
相关推荐
夜之眷属10 分钟前
PriorityQueue:for-each 遍历和 poll 取出,顺序一样吗?
java·服务器·数据结构·后端·算法
地平线开发者1 小时前
不是线程越多越快:用 hrt_model_exec 在 征程6M 上给 YOLOv5x 建立性能基线
算法
姜鱼问生1 小时前
fail2ban 实战:从默认配置到生产可用
后端·算法·架构
垆边人似月.1 小时前
华为题:全排列
算法·深度优先·图论
杜 硕2 小时前
快速排序详解01
数据结构·算法·排序算法
Matlab程序猿2 小时前
【MATLAB源码-第459期】基于matlab的D-H模型与阻尼最小二乘逆运动学的六自由度机械臂五次轨迹规划及动力学前馈PD控制仿真。
人工智能·算法·matlab·d-h建模·六自由度串联机械臂
信奥卷王2 小时前
[GESP202606 六级] 满二叉树
数据结构·算法
积流成海2 小时前
用代码实现哈希计算器:Web Crypto API 实战
前端·算法·哈希算法·哈希函数·盘子工具站
Nil2082 小时前
leetcode 300最长递增子序列
算法·leetcode·职场和发展
垆边人似月.3 小时前
华为机试题 :最大数
c++·算法·华为