力扣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++;
        }
    }
};
相关推荐
园小异4 分钟前
2026年技术面试完全指南:从算法到系统设计的实战突破
算法·面试·职场和发展
m0_706653236 分钟前
分布式系统安全通信
开发语言·c++·算法
天天爱吃肉82181 小时前
跟着创意天才周杰伦学新能源汽车研发测试!3年从工程师到领域专家的成长秘籍!
数据库·python·算法·分类·汽车
alphaTao1 小时前
LeetCode 每日一题 2026/2/2-2026/2/8
算法·leetcode
甄心爱学习1 小时前
【leetcode】判断平衡二叉树
python·算法·leetcode
颜酱1 小时前
从二叉树到衍生结构:5种高频树结构原理+解析
javascript·后端·算法
不知名XL2 小时前
day50 单调栈
数据结构·算法·leetcode
@––––––2 小时前
力扣hot100—系列2-多维动态规划
算法·leetcode·动态规划
xsyaaaan2 小时前
代码随想录Day31动态规划:1049最后一块石头的重量II_494目标和_474一和零
算法·动态规划
Jay Kay3 小时前
GVPO:Group Variance Policy Optimization
人工智能·算法·机器学习