【算法】双指针划分思想妙解移动零

这篇具有很好参考价值的文章主要介绍了【算法】双指针划分思想妙解移动零。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【算法】双指针划分思想妙解移动零,# 双指针,算法

Problem: 283. 移动零

思路

首先我们来讲一下本题的思路

  • 本题主要可以归到【数组划分/数组分块】这一类的题型。我们将一个数组中的所有元素划分为两段区间,左侧是非零元素,右侧是零元素

【算法】双指针划分思想妙解移动零,# 双指针,算法

  • 那解决这一类的题我们首先想到的就是【双指针算法】,学习过C语言的同学应该就可以知道指针是比较繁琐和复杂,如果有兴趣学习的同学可以看看我的这篇文章 链接
  • 不过在这里呢我们不需要去使用int*这种指针,而是直接使用数组下标来充当指针即可

好,那我们就来看看这个双指针到底是怎样的,要如何去使用

  • 两个指针的作用
    • 【cur】: 从左往右扫描数组,遍历数组
    • 【dest】:已处理的区间内,非零元素的最后一个位置
  • 可以看到,cur是我们用来遍历数组的,从[cur, n - 1]就是还未处理的元素;那么从[0, cur]就是已经处理过的元素,但是呢本题的要求是我们要划分出【零元素】与【非零元素】,所以呢前面的区间我们可以再度划分为[0, dest][dest + 1, cur - 1]

【算法】双指针划分思想妙解移动零,# 双指针,算法

小结一下:

[0, dest] [dest + 1, cur - 1] [cur, n - 1]

  • [0, dest] —— 非零元素
  • [dest + 1, cur - 1] —— 零元素
  • [cur, n - 1] —— 未处理元素

算法图解分析

接下去我们就通过画算法图解的形式来模拟一下解题的过程

  • 我们就以题目中所给出的第一个示例为例来进行讲解,因为在一开始我们还没处理过任何的非零元素,所以对于[0, cur - 1]这段区间是没有任何数据的,所以在一开始我们可以将【dest】这个指针置于-1的位置

【算法】双指针划分思想妙解移动零,# 双指针,算法

  • 因为我们需要将非0元素移动到前面,所以呢如果遇到了0元素的话,cur++即可,将其留在这个位置上

【算法】双指针划分思想妙解移动零,# 双指针,算法

  • 那当我们遇到非0元素时,就需要将其交换到前面去,那我们[0, dest]这个区间就是用来存放非0元素的,此时多了一个元素的话那dest就要加1,原本其是指向-1这个位置,那我们可以使用++dest来完成

【算法】双指针划分思想妙解移动零,# 双指针,算法

  • 接下去,当数据交换过来后,我们可以去对照上面的这三个区间,可以发现最左侧是非0元素,中间是0元素,右侧呢则是待处理的元素。接下去我们又碰到了0元素,所以cur++

【算法】双指针划分思想妙解移动零,# 双指针,算法

  • cur再后移之后呢,我们又碰到了非0元素,继续让dest上来然后交换二者位置上的元素

【算法】双指针划分思想妙解移动零,# 双指针,算法

  • 那现在我们再来看这三个区间,左侧还是保持为【非0元素】,中间为【0元素】,右侧的话则是【待处理的元素】

【算法】双指针划分思想妙解移动零,# 双指针,算法

  • 然后碰到非0元素后,继续让++dest,然后做交换

【算法】双指针划分思想妙解移动零,# 双指针,算法

  • 最后的话我们来看看这个处理完后的整个区间元素:非0元素都在前面,而0元素则都在后面,[cur, n - 1]的这段区间也不存在了,说明已经没有待处理元素了

【算法】双指针划分思想妙解移动零,# 双指针,算法

复杂度

接下去我们来分析一下本题的时空复杂度

  • 时间复杂度:

本算法的核心思路参考的是【快速排序】的区间划分,我们这里就是在不断遍历数组的过程中,以中间的0作为分割,然后左侧是非0元素,右侧是未处理的元素。在处理的过程中我们只是遍历了一次这个数组,所以复杂度为 O ( n ) O(n) O(n)

  • 空间复杂度:

在本题中我们并没有去开出额外的空间,所以复杂度为 O ( 1 ) O(1) O(1)

Code

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

【算法】双指针划分思想妙解移动零,# 双指针,算法文章来源地址https://www.toymoban.com/news/detail-659481.html

到了这里,关于【算法】双指针划分思想妙解移动零的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【算法专题突破】双指针 - 移动零(1)

    目录 写在前面 1. 题目解析 2. 算法原理 3. 代码编写 写在最后: 在进行了剑指Offer和LeetCode hot100的毒打之后, 我决心系统地学习一些经典算法,增强我的综合算法能力。 题目链接:283. 移动零 - 力扣(Leetcode) 读完题目大概就能明白他的意思, 就是在不改变其他数字的情况下

    2024年02月11日
    浏览(40)
  • 【算法挨揍日记】day01——双指针算法_移动零、 复写零

    283. 移动零 https://leetcode.cn/problems/move-zeroes/ 题目: 给定一个数组  nums ,编写一个函数将所有  0  移动到数组的末尾,同时保持非零元素的相对顺序。 请注意  ,必须在不复制数组的情况下原地对数组进行操作。    解题思路: 我们可以利用两个指针(dest和cur)的方法,

    2024年02月11日
    浏览(34)
  • 【算法专题--双指针算法】leetcode--283. 移动零、leetcode--1089. 复写零

    🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 双指针 常见的双指针有两种形式,一种是对撞指针,⼀种是左右指针。 对撞指针:一般用于顺序结构中

    2024年03月17日
    浏览(45)
  • 刷题(双指针思想/滑动窗口思想/l螺旋矩阵)

    刚开始自己做就是无脑ac的,sort: 但是时间复杂度有问题, 是O(nlogn)的时间复杂度 提升:用双指针的思想:时间复杂度为O(n) 使用 双指针 的思想解决本题的思路: 以数组 为例: 输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100] 因为输入的数组是递增的,因此,平方后的最大值,只

    2023年04月08日
    浏览(52)
  • 【Leetcode刷题(数据结构)】:三路划分与三数随机取中的思想实现快速排序的再优化

    快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中 的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右 子序列中所有元素均大于基准值,然后最左右子序列重复该过程

    2024年02月08日
    浏览(46)
  • 移动通信网络规划:覆盖场景划分

    一、覆盖场景划分的意义 移动通信网络在实现广度覆盖的基础上,要想进一步提升网络质量,实现深度覆盖,就应该分场景讨论深度覆盖解决方案,网络深度覆盖相比从前更趋向于准确、精细、可发展的趋势,因此需要对不同覆盖场景进行分析,并选择最合理的覆盖技术和方

    2024年01月19日
    浏览(47)
  • 【C++11(三)】智能指针详解--RAII思想&循环引用问题

    💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C++从入门到精通⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习C++   🔝🔝 相信学C++的同学或多或少的听说过 智能指针这个词,博主刚听见这个词时 ,觉得它应该很复杂,并且很高大上,但不 管是多牛的东西,都是人写

    2024年02月04日
    浏览(46)
  • LeetCode-763. 划分字母区间【贪心 哈希表 双指针 字符串】

    给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。 注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。 返回一个表示每个字符串片段的长度的列表。 示例 1: 输入:s = “ababcbacadefegdehijhklij” 输

    2024年04月10日
    浏览(56)
  • 《移动互联网技术》 第十章 系统与通信: 掌握Android系统的分层架构设计思想和基于组件的设计模式

    🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍》学会IDEA常用操作,工作效率翻倍~💐 🪁🍁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬

    2024年02月16日
    浏览(56)
  • 【C++ 观察者模式 思想理解】C++中的观察者模式:松耦合设计与动态交互的艺术,合理使用智能指针观察者

    在进入技术细节之前,理解观察者模式(Observer Pattern)的基本概念和它在现代编程中的重要性是至关重要的。 观察者模式是一种设计模式,它定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。在C++中,这个

    2024年01月24日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包