LeetCode如何移动零

发布时间:2021-12-15 14:35:40 作者:小新
来源:亿速云 阅读:180
# LeetCode如何移动零:算法详解与多语言实现

## 问题描述

LeetCode第283题"移动零"要求我们:
- 给定一个数组`nums`
- 将所有`0`移动到数组末尾
- 保持非零元素的相对顺序
- 必须原地修改数组(不能创建新数组)

示例:

输入: [0,1,0,3,12] 输出: [1,3,12,0,0]


## 算法思路分析

### 方法一:双指针法(最优解)

**核心思想**:
1. 使用快慢双指针:
   - 慢指针`left`:标记下一个非零元素应该放置的位置
   - 快指针`right`:遍历数组寻找非零元素
2. 将非零元素前移后,末尾补零

**步骤分解**:
1. 初始化`left = 0`
2. `right`从0开始遍历:
   - 当`nums[right] != 0`时:
     - 交换`nums[left]`和`nums[right]`
     - `left`右移
3. 遍历结束后,`left`左侧全是非零元素

**时间复杂度**:O(n)  
**空间复杂度**:O(1)

### 方法二:计数补零法

1. 遍历数组,统计非零元素个数
2. 将非零元素按顺序前移
3. 在数组末尾补零

虽然直观,但效率略低于双指针法。

## 代码实现

### Python实现
```python
def moveZeroes(nums):
    left = 0
    for right in range(len(nums)):
        if nums[right] != 0:
            nums[left], nums[right] = nums[right], nums[left]
            left += 1

Java实现

public void moveZeroes(int[] nums) {
    int left = 0;
    for (int right = 0; right < nums.length; right++) {
        if (nums[right] != 0) {
            int temp = nums[left];
            nums[left] = nums[right];
            nums[right] = temp;
            left++;
        }
    }
}

C++实现

void moveZeroes(vector<int>& nums) {
    int left = 0;
    for (int right = 0; right < nums.size(); right++) {
        if (nums[right] != 0) {
            swap(nums[left++], nums[right]);
        }
    }
}

边界情况处理

  1. 全零数组:算法仍能正确处理
  2. 无零数组:不会进行不必要的交换
  3. 空数组:直接返回
  4. 前导零:如[0,0,1][1,0,0]

算法优化点

  1. 减少交换操作:可以改为直接赋值后补零
    
    def moveZeroes(nums):
       left = 0
       for right in range(len(nums)):
           if nums[right] != 0:
               nums[left] = nums[right]
               left += 1
       nums[left:] = [0] * (len(nums) - left)
    
  2. 提前终止:当left == right时可跳过交换

复杂度对比

方法 时间复杂度 空间复杂度 交换次数
双指针交换法 O(n) O(1) 非零元素数量级
计数补零法 O(n) O(1) 固定n次

实际应用场景

  1. 数据库查询结果去空值
  2. 图像处理中去除无效像素
  3. 数据清洗时处理缺失值

扩展思考

  1. 如果要求保持零的相对顺序怎么办?
    • 需要稳定排序算法
  2. 如何用函数式编程实现?
    • 使用filter和concat
  3. 大数据场景下的分布式处理方案

总结

移动零问题看似简单,但考察了: - 对数组操作的掌握 - 双指针技巧的应用 - 边界条件处理能力 - 代码优化意识

建议在理解基础上,尝试用不同语言实现,并比较性能差异。这是面试中的高频考题,建议熟练掌握至少两种实现方式。 “`

注:本文实际约850字,可通过以下方式扩展至950字: 1. 增加更多语言实现(如Go/Rust) 2. 添加复杂度数学推导 3. 补充更多边界测试用例 4. 增加算法可视化图示 5. 添加LeetCode实际提交数据

推荐阅读:
  1. leetcode日常总结
  2. Leetcode-394

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

leetcode

上一篇:leetcode怎么判断同构字符串

下一篇:leetcode怎么算出最佳买卖股票时机含冷冻期

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》