【双指针】专题:LeetCode 283题解——移动零

news2025/4/16 3:21:46

移动零

  • 一、题目链接
  • 二、题目
  • 三、题目解析
  • 四、算法原理
    • 两个指针的作用以及三个区间
    • 总结
  • 五、与快速排序的联系
  • 六、编写代码
  • 七、时间复杂度、空间复杂度

一、题目链接

移动零

二、题目

在这里插入图片描述

三、题目解析

“保持非零元素的相对顺序”,比如,示例1中非零元素1在前、3在中间、12在最后,那么移动完数据后还是要保持1在前、3在中间、12在最后,也就是一直保持[1, 3, 12]的顺序。

四、算法原理

移动零这题是可以划分到数组划分/数组分块这一类题里的。

数组划分/数组分块的特点:给一个数组,在制定的规则/标准下将数组划分若干个区间。

本题中制定的规则/标准就是将非0元素移动到数组的前面,0元素移动到数组的后面。因此在该规则下可以把数组划分成两个区间。

在这里插入图片描述

数组划分/数组分块这一类题里涉及到的算法就是双指针算法,但是数组中不是真的用int*这样的指针,数组中是利用数组下标来充当指针


在这里插入图片描述

已处理的区间的目的是达成题目中的要求:已处理区间中左边区间是非0元素,右边区间是0元素。而dest就是非0元素与0元素的分割线。

两个指针的作用以及三个区间

两个指针的作用:
cur:从左往右遍历数组。
dest:已处理的区间内,非零元素的最后一个位置。

三个区间:

都是左闭右闭区间

在这里插入图片描述


两个指针的作用以及三个区间要在解题过程中牢记

cur要遍历数组,所以一开始在下标0处。dest一开始在下标-1处,原因是还没有处理数据。(牢记两个指针的作用以及三个区间,这时是满足的。)这时cur指向元素0。

在这里插入图片描述

当cur遇到元素0,不做任何处理,直接++cur。(满足两个指针的作用以及三个区间,元素0区间[dest + 1,cur - 1]此时就一个0;待处理区间[cur,n - 1])这时cur指向非0元素。

在这里插入图片描述

当cur指向非0元素,非0元素肯定要放到第一个区间的,加一个非0元素就要dest++,然后交换cur、dest指向的元素(注意:不是向前覆盖,这样元素0就不见了)。此时cur所指元素是已经处理过了,所以cur++(满足两个指针的作用以及三个区间)。上述过程转换成代码:swap(dest + 1,cur); dest++,cur++;

在这里插入图片描述


重复上述过程,cur为下标n(数组的元素)时就跳出循环。最后这块数组是被划分成两个区间,即非0元素区间以及0元素区间。

在这里插入图片描述


总结

cur从前往后遍历的过程中:
1、遇到 0 元素:cur++
2、遇到 非0 元素:swap(dest + 1,cur); cur++,dest++;

五、与快速排序的联系

其实快速排序的核心就是数组分块,若是像本题一样用双指针算法,根据基准元素tmp将数组划分成2个区间,那么分析过程以及代码都是与本题一样的。

在这里插入图片描述

#include <iostream>
using namespace std;
int _QuickSort(int arr[], int left, int right)
{
	int keyi = left;
	int dest = keyi;
	for (int cur = dest + 1; cur <= right; ++cur)
		if (arr[cur] <= arr[keyi] && ++dest != cur )
			swap(arr[cur], arr[dest]);
	swap(arr[keyi], arr[dest]);
	return dest;
}
void QuickSort(int* arr, int left, int right)
{
	if (left >= right)
	{
		return;
	}
	// 找基准值的下标
	int keyi = _QuickSort(arr, left, right);
	// [left, keyi - 1]  [keyi + 1, right]
	QuickSort(arr, left, keyi - 1);
	QuickSort(arr, keyi + 1, right);
}
int main()
{
	int arr[] = { 6, 1, 2, 7, 9, 3 };
	size_t n = sizeof(arr) / sizeof(arr[0]);
	QuickSort(arr, 0, n - 1);
	for (size_t i = 0; i < n; ++i)
	{
		cout << arr[i] << " ";
	}
	cout << endl;
	return 0;
}

快速排序这里用双指针算法,只是把数组分成两块,一旦遇到都是相同的数据时,时间复杂度会逼近O(n^2)。

后面“颜色划分”一题,会把数组划分成三块,用这一算法写快速排序才是最优的。

六、编写代码

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int cur = 0, dest = -1;
        while (cur < nums.size())
        {
            if (nums[cur] != 0)
            {
                swap(nums[dest + 1], nums[cur]);
                dest++;
                cur++;
            }
            else
            {
                cur++;
            }
        }
    }
};

简化代码:

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        for (int dest = -1, cur = 0; cur < nums.size(); cur++)// nums[cur]为0还是非0都会++
            if (nums[cur])// 处理非0元素
                swap(nums[++dest], nums[cur]);
    }
};

七、时间复杂度、空间复杂度

一层for循环,cur、dest指针只会从前向后移动,并且这里只判断cur,也就是cur扫描数组一遍就能将数组划分,因此时间复杂度是最优的O(n)。

只用了两个变量cur、dest,因此空间复杂度是O(1)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2334823.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2025蓝桥杯JavaB组

说明 博主自己水平有限&#xff0c;而且答案也不一定对&#xff0c;下面代码和思路仅作分享。我只把我考场上做了的写出来了&#xff0c;有什么问题欢迎评论区交流。 A&#xff1a;逃离高塔 思路&#xff1a; 由于有了去年的经验&#xff0c;所以一上来我就是找规律&#xf…

SQL学习--基础语法学习

SQL和excle对比 学习目标 单表查询 项目背景 SQL 练习环境 SQL Online Compiler - Next gen SQL Editor 商品信息表&#xff1a;https://study-zhibo.oss-cn-shanghai.aliyuncs.com/test/%E5%95%86%E5%93%81%E4%BF%A1%E6%81%AF%E8%A1%A8.csv 订单明细表&#xff1a;https://…

MATLAB2022b安装

1 从百度网盘下载MATLAB2022b&#xff0c;下载完成后解压到某个文件夹&#xff1b; 链接: MATLAB2022b 提取码: 6666 2 打开解压后的文件夹&#xff0c;进入setup文件夹&#xff0c;双击打开“setup.exe”文件&#xff1b; 3 在弹出窗口中选择“高级选项”-->“我有文件安…

架构总览怎么写,才算工业级?

📈系统架构文档是整个项目最重要的起点,但很多人第一章就“写穿了”: 不是写得太细,就是没有重点。想要写出高质量、能协作、能传承的架构文档,这一篇会告诉你应该怎么做—— ✅ 架构总览的终极目标 明确边界、定义角色、画清数据流 别讲执行细节,别深入函数调用。 ✅ 架…

Datawhale 入驻 GitCode:以开源力量推动 AI 教育公平与创新

在 AI 技术深度重塑教育生态的今天&#xff0c;国内首个 AI 开源学习社区 —— Datawhale 正式加入 GitCode 开源平台&#xff01;作为覆盖全球 3000 高校、培养超百万 AI 人才的创新社区&#xff0c;Datawhale 将通过开源协作模式&#xff0c;为人工智能教育公平注入新动能&a…

ChatDBA:一个基于AI的智能数据库助手

今天给大家介绍一个基于 AI 大语言模型实现数据库故障诊断的智能助手&#xff1a;ChatDBA。 ChatDBA 是由上海爱可生信息技术股份有限公司开发&#xff0c;通过对话交互&#xff0c;提供数据库故障诊断、专业知识学习、SQL 生成和优化等功能&#xff0c;旨在提升 DBA 工作效率。…

MacOS中的鼠标、触控板的设置研究

一、背景和写这篇文章的原因 想搞清楚和配置好鼠标&#xff0c;比如解决好为什么我的滚动那么难用&#xff1f;怎么设置滚轮的方向跟windows相同&#xff1f;调整双击速度&#xff0c;调整鼠标滚轮左右拨动的"冷却时间"。 二、各种设置之详细解释 1. MacOS设置 -&…

asp.net core 项目发布到 IIS 服务器

目录 一、VS2022 发布 二、设置IIS服务 三、配置IIS管理器 &#xff08;一&#xff09;打开IIS管理器 &#xff08;二&#xff09;添加站台 &#xff08;三&#xff09;配置应用程式集区 四、安装ASP.NET Core Hosting Bundle 五、设定IIS的日志位置 六、测试 一、VS2…

【Nodebb系列】Nodebb笔记写入方案

NodeBB写入方案 前言 最近在整理以前记录的碎片笔记&#xff0c;想把它们汇总到NodeBB中&#xff0c;方便管理和浏览。但是笔记内容有点多&#xff0c;并且用发帖的形式写到NodeBB中会丢失时间信息&#xff0c;因此整理了一套NodeBB写入方案&#xff0c;大致流程如下&#xf…

计算机视觉——基于YOLOV8 的人体姿态估计训练与推理

概述 自 Ultralytics 发布 YOLOV5 之后&#xff0c;YOLO 的应用方向和使用方式变得更加多样化且简单易用。从图像分类、目标检测、图像分割、目标跟踪到关键点检测&#xff0c;YOLO 几乎涵盖了计算机视觉的各个领域&#xff0c;似乎已经成为计算机视觉领域的“万能工具”。 Y…

鸿蒙小案例---心情日记

效果演示 代码实现 import { router, window } from kit.ArkUIEntry Component struct Index {async aboutToAppear(): Promise<void> {let w await window.getLastWindow(getContext())w.setWindowSystemBarProperties({statusBarColor: #00C6C3,statusBarContentColo…

el-tree 实现树形菜单子级取消选中后父级选中效果不变

背景 在复杂的企业级管理系统中,树形菜单是一种常见的数据展示和交互组件。传统的树形菜单通常存在以下交互局限: 子节点取消选中时,父节点会自动取消选中无法满足复杂的权限分配和数据筛选场景实际应用场景: 组织架构权限管理多层级资源分配复杂的数据筛选与展示实现需求…

Java虚拟机——JVM(Java Virtual Machine)解析一

1.JVM是什么&#xff1f; 1.1 JVM概念 Java Virtual Machine (JVM) 是JDK的核心组件之一&#xff0c;它使得 Java 程序能够在任何支持 JVM 的设备或操作系统上运行&#xff0c;而无需修改源代码 JDK是什么&#xff0c;JDK和JVM是什么关系&#xff1f;1.Java IDE(Integrated …

【源码】SpringMvc源码分析

文章目录 SpringMVC 基础回顾​核心组件源码分析​DispatcherServlet​HandlerMapping​HandlerAdapter​ViewResolver​ 请求处理流程源码解析​ 在当今的 Java Web 开发领域&#xff0c;SpringMVC 无疑是最为广泛应用的 Web 框架之一。它以其强大的功能、灵活的配置以及高度的…

tcp特点+TCP的状态转换图+time_wait详解

tcp特点TCP的状态转换图time wait详解 目录 一、tcp特点解释 1.1 面向连接 1.1.1 连接建立——三次握手 1.1.2 连接释放——四次挥手 1.2 可靠的 1.2.1 应答确认 1.2.2 超时重传 1.2.3 乱序重排 1.2.4 去重 1.2.5 滑动窗口进行流量控制 1.3 流失服务&#xff08;字节…

高支模自动化监测解决方案

1.行业现状 高大模板支撑系统在浇筑施工过程中&#xff0c;诸多重大安全风险点进行实时自动化安全监测的解决方案主要监测由于顶杆失稳、扣件失效、承压过大等引起的支撑轴力、模板沉降、相对位移、支撑体系倾斜等参数变化。系统采用无线自动组网、高频连续采样&#xff0c;实时…

OpenCV 图形API(24)图像滤波-----双边滤波函数bilateralFilter()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 应用双边滤波到图像。 该函数对输入图像应用双边滤波&#xff0c;如 http://www.dai.ed.ac.uk/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Fil…

HarmonyOS中的多线程并发机制

目录 多线程并发1. 多线程并发概述2 多线程并发模型3 TaskPool简介4 Worker简介4.1 Woker注意事项4.2 Woker基本用法示例 5. TaskPool和Worker的对比5.1 实现特点对比5.2 适用场景对比 多线程并发 1. 多线程并发概述 并发模型是用来实现不同应用场景中并发任务的编程模型&…

【随手笔记】QT避坑一(串口readyRead信号不产生)

问题描述&#xff1a; 使用QT5.15.2版本 测试串口readyRead绑定槽函数&#xff0c;接收到数据后 不能触发 试了很多网友的程序&#xff0c;他们的发布版本可以&#xff0c;但是源码我编译后就不能触发&#xff0c;判断不是代码的问题 看到有人提到QT版本的问题&#xff0c;于…

【产品】ToB产品需求分析

需求分析流程 合格产品经理 帮助用户、引导用户、分析需求、判断需求、设计方案 不能苛求用户提出合理、严谨的需求&#xff0c;这不是用户的责任和义务&#xff0c;而应该通过自己的专业能力来完成需求的采集工作 #mermaid-svg-ASu8vocank48X6FI {font-family:"trebuche…