【经典算法】LeetCode 283. 移动零(Java/C/Python3/Go实现含注释说明,Easy)

简介: 【经典算法】LeetCode 283. 移动零(Java/C/Python3/Go实现含注释说明,Easy)
  • 作者简介:阿里非典型程序员一枚 ,记录在大厂的打怪升级之路。 一起学习Java、大数据、数据结构算法(公众号同名
  • ❤️觉得文章还不错的话欢迎大家点赞👍➕收藏⭐️➕评论,💬支持博主,记得点个大大的关注,持续更新🤞
    ————————————————-

移动零

  • 标签(题目类型):数组,双指针

题目描述

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:

输入: [0,1,0,3,12]

输出: [1,3,12,0,0]

说明:

必须在原数组上操作,不能拷贝额外的数组。

尽量减少操作次数。

原题:283. 移动零

思路及实现

方式一:双指针

思路

使用两个指针 iji 用于遍历数组,j 用于指向非零元素应该存放的位置。遍历数组时,如果当前元素不为零,则将其交换到 j 的位置,并将 j 后移一位。这样,遍历结束后,所有非零元素都移动到了数组的前面,而后面的位置都是零。

代码实现

Java版本
public void moveZeroes(int[] nums) {
    int j = 0; // 指向非零元素应该存放的位置
    for (int i = 0; i < nums.length; i++) {
        if (nums[i] != 0) {
            // 如果当前元素不为零,则交换到 j 的位置,并将 j 后移一位
            int temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
            j++;
        }
    }
}

说明:

  • 变量 j 初始化为0,表示非零元素应该存放的起始位置。
  • 遍历数组 nums,如果当前元素不为零,则与 nums[j] 交换位置,并将 j 后移一位。
  • 遍历结束后,所有非零元素都移动到了数组的前面,后面的位置都是零。
C语言版本
void moveZeroes(int* nums, int numsSize) {
    int j = 0; // 指向非零元素应该存放的位置
    for (int i = 0; i < numsSize; i++) {
        if (nums[i] != 0) {
            // 如果当前元素不为零,则交换到 j 的位置,并将 j 后移一位
            int temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
            j++;
        }
    }
}

说明:

  • 与Java版本类似,使用 j 指针来记录非零元素应该存放的位置。
  • 交换非零元素到 j 的位置,并更新 j 的值。
Python3版本
def moveZeroes(nums):
    j = 0  # 指向非零元素应该存放的位置
    for i in range(len(nums)):
        if nums[i] != 0:
            # 如果当前元素不为零,则交换到 j 的位置,并将 j 后移一位
            nums[i], nums[j] = nums[j], nums[i]
            j += 1

说明:

  • 使用Python的简洁语法,直接交换元素的位置。
  • 变量 j 的作用和逻辑与Java和C版本相同。
Golang版本
func moveZeroes(nums []int) {
    j := 0 // 指向非零元素应该存放的位置
    for i := 0; i < len(nums); i++ {
        if nums[i] != 0 {
            // 如果当前元素不为零,则交换到 j 的位置,并将 j 后移一位
            nums[i], nums[j] = nums[j], nums[i]
            j++
        }
    }
}

说明:

  • Golang的实现逻辑与Java和C类似,通过 j 指针来记录非零元素应该存放的位置。
  • 交换元素时,使用Golang的多返回值赋值特性。

复杂度分析

  • 时间复杂度:O(n),其中 n 是数组的长度。只需要遍历数组一次。
  • 空间复杂度:O(1)。只使用了常数级别的额外空间。

方式二:计数法

思路

首先遍历数组,统计非零元素的个数。然后再次遍历数组,将非零元素按顺序放到数组的前面,其余位置填充为零。

代码实现

Java版本
public void moveZeroes(int[] nums) {
    int count = 0; // 统计非零元素的个数
    for (int num : nums) {
        if (num != 0) {
            count++;
        }
    }
    
    int index = 0; // 非零元素应该存放的位置索引
    for (int num : nums) {
        if (num != 0) {
            nums[index] = num; // 将非零元素按顺序放到数组的前面
            index++;
        }
    }
    
    // 将剩余位置填充为零
    while (index < nums.length) {
        nums[index] = 0;
        index++;
    }
}

说明:

  • 第一次遍历数组,统计非零元素的个数。
  • 第二次遍历数组,将非零元素按顺序放到数组的前面。
  • 最后,将剩余的位置填充为零。
C语言版本
void moveZeroes(int* nums, int numsSize) {
    int count = 0; // 统计非零元素的个数
    for (int i = 0; i < numsSize; i++) {
        if (nums[i] != 0) {
            count++;
        }
    }
    
    int index = 0; // 非零元素应该存放的位置索引
    for (int i = 0; i < numsSize; i++) {
        if (nums[i] != 0) {
            nums[index] = nums[i]; // 将非零元素按顺序放到数组的前面
            index++;
        }
    }
    
    // 将剩余位置填充为零
    while (index < numsSize) {
        nums[index] = 0;
        index++;
    }
}

说明:

  • 与Java版本类似,使用两次遍历,第一次统计非零元素个数,第二次将非零元素按顺序放到数组前面,并将剩余位置填充为零。
Python3版本
def moveZeroes(nums):
    count = sum(1 for num in nums if num != 0) # 统计非零元素的个数
    index = 0 # 非零元素应该存放的位置索引
    for num in nums:
        if num != 0:
            nums[index] = num # 将非零元素按顺序放到数组的前面
            index += 1
    
    # 将剩余位置填充为零
    while index < len(nums):
        nums[index] = 0
        index += 1

说明:

  • 使用Python的简洁语法和特性来实现计数和填充操作。
Golang版本
func moveZeroes(nums []int) {
    count := 0 // 统计非零元素的个数
    for _, num := range nums {
        if num != 0 {
            count++
        }
    }
    
    index := 0 // 非零元素应该存放的位置索引
    for _, num := range nums {
        if num != 0 {
            nums[index] = num // 将非零元素按顺序放到数组的前面
            index++
        }
    }
    
    // 将剩余位置填充为零
    for i := index; i < len(nums); i++ {
        nums[i] = 0
    }
}

说明:

  • Golang版本的实现逻辑与其他语言版本类似,通过两次遍历来实现移动零元素。

复杂度分析

  • 时间复杂度:O(n),其中 n 是数组的长度。需要遍历数组两次。
  • 空间复杂度:O(1)。只使用了常数级别的额外空间。

总结

方式 优点 缺点 时间复杂度 空间复杂度
方式一(双指针) 代码简洁,易于理解 无明显缺点 O(n) O(1)
方式二(计数法) 逻辑清晰,易于实现 需要遍历数组两次 O(n) O(1)

相似题目

相似题目 难度 链接
leetcode 27 简单 力扣27
leetcode 28 简单 力扣28

欢迎一键三连(关注+点赞+收藏),技术的路上一起加油!!!代码改变世界

  • 关于我:阿里非典型程序员一枚 ,记录在大厂的打怪升级之路。 一起学习Java、大数据、数据结构算法公众号同名),回复暗号,更能获取学习秘籍和书籍等
相关文章
|
5月前
|
算法 搜索推荐 JavaScript
基于python智能推荐算法的全屋定制系统
本研究聚焦基于智能推荐算法的全屋定制平台网站设计,旨在解决消费者在个性化定制中面临的选择难题。通过整合Django、Vue、Python与MySQL等技术,构建集家装设计、材料推荐、家具搭配于一体的一站式智能服务平台,提升用户体验与行业数字化水平。
|
5月前
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
6月前
|
存储 算法 调度
【复现】【遗传算法】考虑储能和可再生能源消纳责任制的售电公司购售电策略(Python代码实现)
【复现】【遗传算法】考虑储能和可再生能源消纳责任制的售电公司购售电策略(Python代码实现)
320 26
|
6月前
|
机器学习/深度学习 算法 机器人
【机器人路径规划】基于D*算法的机器人路径规划(Python代码实现)
【机器人路径规划】基于D*算法的机器人路径规划(Python代码实现)
338 0
|
6月前
|
机器学习/深度学习 算法 机器人
【机器人路径规划】基于改进型A*算法的机器人路径规划(Python代码实现)
【机器人路径规划】基于改进型A*算法的机器人路径规划(Python代码实现)
487 0
|
6月前
|
机器学习/深度学习 编解码 算法
【机器人路径规划】基于迪杰斯特拉算法(Dijkstra)的机器人路径规划(Python代码实现)
【机器人路径规划】基于迪杰斯特拉算法(Dijkstra)的机器人路径规划(Python代码实现)
552 4
|
6月前
|
机器学习/深度学习 算法 机器人
【机器人路径规划】基于A*算法的机器人路径规划研究(Python代码实现)
【机器人路径规划】基于A*算法的机器人路径规划研究(Python代码实现)
837 4
|
6月前
|
机器学习/深度学习 算法 机器人
【机器人路径规划】基于深度优先搜索(Depth-First-Search,DFS)算法的机器人路径规划(Python代码实现)
【机器人路径规划】基于深度优先搜索(Depth-First-Search,DFS)算法的机器人路径规划(Python代码实现)
351 3
|
6月前
|
算法 机器人 定位技术
【机器人路径规划】基于流场寻路算法(Flow Field Pathfinding)的机器人路径规划(Python代码实现)
【机器人路径规划】基于流场寻路算法(Flow Field Pathfinding)的机器人路径规划(Python代码实现)
421 4
机器学习/深度学习 算法 自动驾驶
1206 0

热门文章

最新文章