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

相关推荐
代码雕刻家14 分钟前
数据结构-3.9.栈在递归中的应用
c语言·数据结构·算法
雨中rain14 分钟前
算法 | 位运算(哈希思想)
算法
Kalika0-02 小时前
猴子吃桃-C语言
c语言·开发语言·数据结构·算法
sp_fyf_20242 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-02
人工智能·神经网络·算法·计算机视觉·语言模型·自然语言处理·数据挖掘
我是哈哈hh4 小时前
专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结
服务器·数据结构·c++·算法·机器学习·深度优先·剪枝
Tisfy4 小时前
LeetCode 2187.完成旅途的最少时间:二分查找
算法·leetcode·二分查找·题解·二分
Mephisto.java4 小时前
【力扣 | SQL题 | 每日四题】力扣2082, 2084, 2072, 2112, 180
sql·算法·leetcode
robin_suli4 小时前
滑动窗口->dd爱框框
算法
丶Darling.4 小时前
LeetCode Hot100 | Day1 | 二叉树:二叉树的直径
数据结构·c++·学习·算法·leetcode·二叉树
labuladuo5204 小时前
Codeforces Round 977 (Div. 2) C2 Adjust The Presentation (Hard Version)(思维,set)
数据结构·c++·算法