力扣hot100-283移动零

简介: 给定数组 `nums`,将所有 0 移至末尾,同时保持非零元素相对顺序,需原地操作。使用双指针:右指针找非零元素,左指针指向下一个非零元素应放置的位置。找到后交换两元素,确保非零元素前移、0 后移。最终一次遍历完成,时间复杂度 O(n),空间复杂度 O(1)。

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:

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:

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++:

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++;
        }
    }
};
目录
相关文章
|
27天前
|
数据采集 人工智能 IDE
告别碎片化日志:一套方案采集所有主流 AI 编程工具
本文介绍了一套基于MCP架构的轻量化、多AI工具代码采集方案,支持CLI、IDE等多类工具,实现用户无感、可扩展的数据采集,已对接Aone日志平台,助力AI代码采纳率分析与研发效能提升。
411 46
告别碎片化日志:一套方案采集所有主流 AI 编程工具
|
20天前
|
机器学习/深度学习 人工智能 自然语言处理
超越规则:AI模型如何学会“思考”?
超越规则:AI模型如何学会“思考”?
209 142
|
存储 缓存 NoSQL
阿里云 Tair KVCache 仿真分析:高精度的计算和缓存模拟设计与实现
阿里云 Tair 推出 KVCache-HiSim,首个高保真 LLM 推理仿真工具。在 CPU 上实现<5%误差的性能预测,成本仅为真实集群的1/39万,支持多级缓存建模与 SLO 约束下的配置优化,助力大模型高效部署。
|
1月前
|
SQL 人工智能 分布式计算
从工单、文档到结构化知识库:一套可复用的 Agent 知识采集方案
我们构建了一套“自动提取 → 智能泛化 → 增量更新 → 向量化同步”的全链路自动化 pipeline,将 Agent 知识库建设中的收集、提质与维护难题转化为简单易用的 Python 工具,让知识高效、持续、低门槛地赋能智能体。
345 36
|
27天前
|
人工智能 运维 监控
进阶指南:BrowserUse + AgentRun Sandbox 最佳实践
本文将深入讲解 BrowserUse 框架集成、提供类 Manus Agent 的代码示例、Sandbox 高级生命周期管理、性能优化与生产部署策略。涵盖连接池设计、安全控制、可观测性建设及成本优化方案,助力构建高效、稳定、可扩展的 AI 浏览器自动化系统。
448 47
|
21天前
|
云安全 安全 Cloud Native
阿里云智能云原生应用保护平台CNAPP(原安全中心)详解:费用价格、功能优势及问题解答FAQ
阿里云全新升级智能云原生应用保护平台(CNAPP),融合CWPP、CSPM、CIEM、CTDR四大能力,提供覆盖“事前-事中-事后”的全链路安全防护。支持多云纳管、自动威胁响应与合规检查,助力企业实现安全左移、风险可视、响应自动化。
|
29天前
|
数据采集 监控 数据可视化
快速上手:LangChain + AgentRun 浏览器沙箱极简集成指南
AgentRun Browser Sandbox 是基于云原生函数计算的浏览器沙箱服务,为 AI Agent 提供安全、免运维的浏览器环境。通过 Serverless 架构与 CDP 协议支持,实现网页抓取、自动化操作等能力,并结合 VNC 实时可视化,助力大模型“上网”交互。
485 43
|
1月前
|
Kubernetes 应用服务中间件 API
应对 Nginx Ingress 退役,是时候理清这些易混淆的概念了
本文希望提供一种更简单的方式,来理解这些容易混淆的技术概念:Nginx、Ingress、Ingress Controller、Ingress API、Nginx Ingress、Higress、Gateway API。
804 71
|
7天前
|
人工智能 自然语言处理 安全
新手小白如何部署OpenClaw(Clawdbot)?阿里云一键部署!
OpenClaw(原Clawdbot/Moltbot)是一款开源AI智能体平台,可部署于自有服务器,通过自然语言调用浏览器、邮件、文件等工具,自动完成文档整理、日程安排、代码编写等任务,数据本地化,隐私安全可控。
132 11
|
27天前
|
SQL 人工智能 Java
告别传统 Text-to-SQL:基于 Spring AI Alibaba 的数据分析智能体 DataAgent 深度解析
DataAgent是基于Spring AI Alibaba生态构建的企业级AI数据分析师,融合NL2SQL、多智能体协作与RAG技术,支持多数据源分析、自动纠错与可视化报告生成,让业务人员零代码获取深度数据洞察。
1143 42
告别传统 Text-to-SQL:基于 Spring AI Alibaba 的数据分析智能体 DataAgent 深度解析