「这是我参与2022首次更文挑战的第21天,活动详情查看:2022首次更文挑战」。
题目描述🌍
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:
输入: nums = [0]
输出: [0]
提示:
- 1 <=
nums.length<= 104 - -231 <=
nums[i]<= 231 - 1
双指针法🔍
解题思路
这道题的解题思路和之前做过的 2 题很像:
所谓的双指针:通常是慢指针指向有效数组末尾,快指针用于遍历数组(以上提及的两题和该题都是如此)
思路:指针 j 顺序遍历数组,一旦遇到 非0 元素,将其覆盖到指针 i 指向的有效数组末尾。此时可以进行两种"移动零"的操作(以下代码演示第二种):
- 再遍历一次数组,将
j指针后边的元素全部赋值为 0. - 首次遍历数组且赋值
nums[i] = nums[j]后,判断i与j指针是否指向同一个元素,若不同,则将j指针指向的位置赋值为 0.
代码
Java
class Solution {
public void moveZeroes(int[] nums) {
// 指针 i 指向有效数组的末位
// 指针 j 用于遍历数组
int i = 0;
for (int j = 0; j < nums.length; j++) {
if (nums[j] != 0) {
nums[i] = nums[j];
if (i != j)
nums[j] = 0;
i++;
// 以上四行代码也可简写为如下代码
// nums[i++] = nums[j];
// nums[j] = ((i - 1) == j ? nums[j] : 0);
}
}
}
}
C++
class Solution {
public:
void moveZeroes(vector<int> &nums) {
int left = 0;
int n = nums.size();
for (int right = 0; right < n; ++right) {
if (nums[right] != 0) {
nums[left] = nums[right];
if (left != right)
nums[right] = 0;
left++;
}
}
}
};
时间复杂度:
空间复杂度:
最后🌅
该篇文章为 「LeetCode」 系列的 No.19 篇,在这个系列文章中:
- 尽量给出多种解题思路
- 提供题解的多语言代码实现
- 记录该题涉及的知识点
👨💻争取做到 LeetCode 每日 1 题,所有的题解/代码均收录于 「LeetCode」 仓库,欢迎随时加入我们的刷题小分队!