双指针1:移动零

🔥个人主页: Milestone-里程碑

❄️个人专栏: <<力扣hot100>> <<C++>><<Linux>>

<<Git>><<MySQL>>

🌟心向往之行必能至

题目描述

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。注意:必须在不复制数组的情况下原地对数组进行操作。

示例

  • 输入:nums = [0,1,0,3,12]
  • 输出:[1,3,12,0,0]

方法一:双指针交换法

思路

我们可以用一个指针 left 来记录当前非零元素应该放置的位置,然后遍历数组。当遇到非零元素时,就将它与 left 位置的元素交换,并让 left 指针右移。这样可以保证 left 指针之前的所有元素都是非零的,且保持了原有顺序。

代码实现

cpp

复制代码
class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int left = 0;
        for (auto& x : nums) {
            if (x != 0) {
                swap(x, nums[left]);
                left++;
            }
        }
    }
};

复杂度分析

  • 时间复杂度:O (n),其中 n 是数组的长度。我们只需要遍历一次数组。
  • 空间复杂度:O (1),只使用了常数级的额外空间。

方法二:覆盖补零法

思路

  1. 先遍历数组,把所有非零元素依次覆盖到数组的前面,用一个变量 stack_size 记录当前覆盖的位置。
  2. 遍历完成后,stack_size 及之后的位置全部补零即可。

代码实现

cpp

复制代码
class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int stack_size = 0;
        // 第一步:把非零元素移到前面
        for (int x : nums) {
            if (x != 0) {
                nums[stack_size++] = x;
            }
        }
        // 第二步:后面的位置全部补零
        while (stack_size < nums.size()) {
            nums[stack_size++] = 0;
        }
    }
};

复杂度分析

  • 时间复杂度:O (n),两次遍历数组,总时间还是线性的。
  • 空间复杂度:O (1),同样是原地操作。

方法对比

方法 优点 缺点
双指针交换法 只需一次遍历,操作次数更少 交换操作会多写几次赋值
覆盖补零法 逻辑直观,容易理解 需要两次遍历,操作次数略多

在进阶要求 "尽量减少操作次数" 时,双指针交换法会更有优势。


总结

这道题的核心是原地修改保持相对顺序,两种方法都能满足要求。

相关推荐
dingzd954 小时前
Facebook强化原创内容分发后跨境品牌如何重做素材策略
大数据·人工智能·新媒体运营·内容营销·跨境
ん贤4 小时前
加密算法(对称、非对称、哈希、签名...)
算法·哈希算法
Mr_sst4 小时前
infra-ai模块宏观设计解析:业务与模型之间的中间层核心架构
大数据·人工智能·ai·llama
无忧智库4 小时前
大型集团数字化用户主数据管理体系建设:从零到一的系统性规划实践(PPT)
大数据
AIwenIPgeolocation5 小时前
IP地址数据服务:驱动电子商务精细化运营与智能风控
大数据·网络协议·tcp/ip
superior tigre5 小时前
78 子集
算法·leetcode·深度优先·回溯
天威?*5 小时前
bitset的数据结构用法
算法·动态规划
yongyoudayee5 小时前
业务语义模型:AI CRM从“能用”到“好用”的技术分水岭
大数据·人工智能
tang777895 小时前
代理IP质量检测实战:Python实现IP可用性、延迟、匿名度自动测试脚本
大数据·爬虫·python·网络协议·tcp/ip
我就是妖怪5 小时前
Kimi K2.6 新手快速上手与实战指南
大数据·人工智能