【LC100】No283. 移动零
题目描述
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
提示:
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
进阶:
你能尽量减少完成的操作次数吗?
示例
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:
输入: nums = [0]
输出: [0]
链接
思路
abandon!
数组开头的一些特殊情况,有时候可以不用单独拿出来判断,融进循环里,无非是多交换几次的消耗。
第一次做题时的心路历程如下:
解法一:两次遍历,一次移动,一次补0
核心思路:把所有不是 0 的元素移动到前面来。
i 用来遍历,j 用来标识从左边数第一个 0 的位置。
代码
class Solution {
public void moveZeroes(int[] nums) {
if (nums == null) return;
int j = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] != 0) {
nums[j] = nums[i];
j++;
}
}
for (; j < nums.length; j++) {
nums[j] = 0;
}
}
}
时间复杂度:O(n)
空间复杂度:O(1)
解法二:一次遍历,快指针遍历,慢指针处理特殊
核心思路:当数组开头是连续非 0 元素时,快慢指针一起向右移动。
慢指针找到左边开始数的第一个 0:快指针处理时,慢指针也处理,仅在处理完成后向右移动。
快指针找到 0 之后的第一个非 0:当非 0 时才处理交换,遇到 0 直接跳过继续向右移动。
代码
class Solution {
public void moveZeroes(int[] nums) {
if (nums == null || nums.length == 1) return;
int left = 0, right = 0;
while (right < nums.length) {
if (nums[right] != 0) {
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
left++;
}
right++;
}
}
}
时间复杂度:O(n)
空间复杂度:O(1)
【LC100】No283. 移动零
https://tiamo495.com//archives/lc100-no283.-yi-dong-ling