1.题目描述
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
-
必须在原数组上操作,不能拷贝额外的数组。
-
尽量减少操作次数。
2.题解
1.空间最优,操作局部优化(双指针)
//主要思路 loop 2 次 第一次将所有非0元素移动到应该在的地方。
//第二次将后面的全部设置为0
public void moveZeroes(int[] nums) {
if (nums.length == 0){
return;
}
int modifyIndex = 0;
for(int i = 0;i<nums.length;i++){
if(nums[i]!=0){
nums[modifyIndex++] = nums[i];
}
}
for(;modifyIndex<nums.length;modifyIndex++){
nums[modifyIndex] = 0;
}
}
时间复杂度:O(n)
2.一次loop
/***
* 思路:快排的思想找到一个中间点的数 比如 -21 -23 4 5 0 找到一个midNum数 作为标尺 来计算
* 因此 在本题中找出所有0 用0作为一个标尺 0左边的都是非0 右边是0
* 通过一个loop就可以了。
* @param nums
*/
public void moveZeroes(int[] nums) {
if (nums.length == 0){
return;
}
int j = 0;
for (int i = 0; i < nums.length ; i++) {
if (nums[i] != 0){
int temp = nums[i];
nums[i] = nums[j];
nums[j++] = temp;
}
}
}
时间复杂度 O(n)
3.滚雪球
/***
* 滚雪球
* 一次loop 记录0的元素,如果不为0 与前面的元素进行交换 直到最后。
* @param nums
*/
public void moveZeroes(int[] nums) {
if (nums.length == 0){
return;
}
int ballSize = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 0){
ballSize++;
}else if (ballSize>0){
nums[i-ballSize] = nums[i];
nums[i] = 0;
}
}
}
时间复杂度:O(n)
参考: