Rust:算法题:移动0

问题描述

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

示例说明:
  • 示例 1:

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

    • 输入:nums = [0]
    • 输出:[0]
约束条件:
  • 1 <= nums.length <= 10^4
  • -2^31 <= nums[i] <= 2^31 - 1

解题思路

一般像数组,有序,并且将其进行数字移动的操作都可以考虑双指针法,因为通常来说都可以降低时间复杂度,如果不用双指针法,可能就需要两层循环,但是用双指针法,一次循环就可以达到两层循环的效果,非常好用!

算法方法

为了解决这个问题,我们采用双指针技巧,通过两个指针 slowfast 来有效地区分非零元素和零。方法可以分为两个主要步骤:

  1. 第一遍扫描 - 将非零元素移动到左边:

    • 使用 fast 遍历数组时,我们用 slow 来跟踪下一个非零元素应该放置的位置。每次在 fast 位置遇到一个非零元素,我们就将其值复制到 slow 指向的位置,然后增加 slow
    • 这个步骤确保所有非零元素都移动到数组的开头,并保持它们原有的顺序。
  2. 第二遍扫描 - 将剩余位置填充为零:

    • slow 指针的位置开始(现在指向最后一个非零元素的下一个位置),我们将数组的其余部分填充为零。

Rust 代码实现

rust 复制代码
impl Solution {
    pub fn move_zeroes(nums: &mut Vec<i32>) {
        let mut slow = 0_usize;
        let mut fast = 0_usize;
        while fast < nums.len() {
            if nums[fast] != 0 {
                nums[slow] = nums[fast];
                slow += 1;
            }
            fast += 1;
        }
        while slow < nums.len() {
            nums[slow] = 0;
            slow += 1;
        }
    }
}

复杂度分析

  • 时间复杂度: 由于算法对数组进行了两次遍历,因此时间复杂度为线性时间复杂度, O(n),其中n是数组中的元素个数。
  • 空间复杂度: 由于操作是就地进行的,并且只使用了恒定数量的额外空间,所以空间复杂度为 O(1)。

为什么双指针方法有效?

双指针方法之所以在"移动零"问题中特别有效,是因为它允许我们在单次或极少的遍历中完成对数组的修改,同时保持非零元素的相对顺序。这种方法使用两个指针(在本问题中是slowfast)分别跟踪特定条件下的元素位置,从而达成如下目的:

  • slow指针:标记了当前已处理序列的末尾,即下一个非零元素应该放置的位置。

  • fast指针:用于遍历数组,寻找非零元素。

  • 这种区分使得算法能够在fast指针寻找到非零元素时,立即将其移动到slow指针的位置,从而将非零元素集中到数组的前端,而不需要额外的数组来存放非零元素或多次遍历数组。

  • 减少赋值操作 :通过只在fast指针找到非零元素时才进行赋值操作,减少了不必要的赋值次数。如果fastslow指向相同的元素,实际上没有必要做赋值操作,因为它们都是非零的,这避免了自赋值。

  • 避免多余的遍历 :一旦所有非零元素都被移动到数组的前面,剩下的位置必定都是零。因此,第二次遍历从slow指针开始,直接将剩余的部分填充为零,无需再次检查这些元素是否为零。Pomelo_刘金。转载请注明原文链接。感谢!

相关推荐
电鱼智能的电小鱼5 小时前
基于电鱼 AI 工控机的智慧工地视频智能分析方案——边缘端AI检测,实现无人值守下的实时安全预警
网络·人工智能·嵌入式硬件·算法·安全·音视频
孫治AllenSun5 小时前
【算法】图相关算法和递归
windows·python·算法
格图素书6 小时前
数学建模算法案例精讲500篇-【数学建模】DBSCAN聚类算法
算法·数据挖掘·聚类
DashVector7 小时前
向量检索服务 DashVector产品计费
数据库·数据仓库·人工智能·算法·向量检索
AI纪元故事会7 小时前
【计算机视觉目标检测算法对比:R-CNN、YOLO与SSD全面解析】
人工智能·算法·目标检测·计算机视觉
夏鹏今天学习了吗7 小时前
【LeetCode热题100(59/100)】分割回文串
算法·leetcode·深度优先
卡提西亚7 小时前
C++笔记-10-循环语句
c++·笔记·算法
还是码字踏实7 小时前
基础数据结构之数组的双指针技巧之对撞指针(两端向中间):三数之和(LeetCode 15 中等题)
数据结构·算法·leetcode·双指针·对撞指针
史不了8 小时前
静态交叉编译rust程序
开发语言·后端·rust
Johnny.Cheung8 小时前
非常好的Rust自动管理内存的例子
rust·内存管理·析构函数