题目
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入:[0,1,0,3,12]
输出:[1,3,12,0,0]
说明:
- 必须在原数组上操作,不能拷贝额外的数组。
- 尽量减少操作次数。
思路
方法一:
从头开始遍历数组,遇到非零数字则将其放到lastNonZeroindex,然后lastNonZeroindex++
第一个for循环结束后所有非零数字都在数组头部,在第二个for循环中将数组尾部的元素全部赋0即可
方法二:
从头开始遍历数组,遇到非零数字则将其与lastNonZeroindex位置的数字交换位置,然后lastNonZeroindex++
Java代码
方法一:
class Solution {
public void moveZeroes(int[] nums) {
int lastNonZeroindex = 0;
// 将所有非零数字都放到数组头部
for(int i = 0; i < nums.length; i++){
if(nums[i] != 0){
nums[lastNonZeroindex++] = nums[i];
}
}
// 将数组尾部的元素全部赋0
for(int j = lastNonZeroindex; j < nums.length; j++){
nums[j] = 0;
}
}
}
空间复杂度: O(1)。仅使用恒定空间。
时间复杂度: O (n )。但是,操作总数仍然不是最佳的。代码执行的总操作(数组写入)是n(元素总数)。
方法二:
class Solution {
public void moveZeroes(int[] nums) {
int lastNonZeroindex = 0;
int temp;
for(int i = 0; i < nums.length; i++){
if(nums[i] != 0){
temp = nums[lastNonZeroindex];
nums[lastNonZeroindex++] = nums[i];
nums[i] = temp;
}
}
}
}
空间复杂度: O(1)。仅使用恒定空间。
时间复杂度: O (n )。但是操作总数是最佳的。代码执行的总操作(数组写入)是非0元素的数量。这给我们提供了比第一个解决方案更好的最佳情况(当大多数元素为0时)。然而,两种算法的最坏情况(当所有元素都是非0时)的复杂性是相同的。