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_刘金。转载请注明原文链接。感谢!

相关推荐
花褪残红青杏小9 小时前
Rust图像处理第6节- 均值模糊 & 中值模糊:3×3 邻域的两种经典玩法
rust·webassembly·图形学
罗西的思考11 小时前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习
子兮曰13 小时前
前端工具链的「Rust 化」:一场没有赢家的军备竞赛?
前端·后端·rust
美团技术团队14 小时前
LongCat 开源 VitaBench 2.0:长期动态智能体基准新标杆
人工智能·算法
星栈15 小时前
写 Dioxus Demo 不难,难的是把它写成项目
前端·rust·前端框架
mCell17 小时前
【锐评】桌面端技术营销:别拿跑分当工程判断
前端·rust·electron
武子康1 天前
调查研究-201 Rust 里的 dev build 和 release build:为什么同一份代码性能差这么多?
后端·架构·rust
doiito1 天前
【Agent Harness】Gliding Horse 的 L2 作战地图:让多 Agent 协作从“摸黑”变成“透明”
ai·rust·架构设计·系统设计·ai agent
To_OC1 天前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC1 天前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode