Question
Given an array nums, write a function to move all 0’s to the end of it while maintaining the relative order of the non-zero elements.For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0].
Note:
1.You must do this in-place without making a copy of the array.
2.Minimize the total number of operations.
思路一
对数组内的元素进行遍历,如果是非0则跳过,如果是0则在后面的元素中找到一个非零的元素,两个元素交换位置。
代码
public class Solution {
public void moveZeroes(int[] nums) {
for(int i = 0;i < nums.length;i++){
if(nums[i] != 0)
continue;
else{
for(int j = i + 1;j < nums.length;j++){
if(nums[j] == 0)
continue;
else{
nums[i] = nums[j];
nums[j] = 0;
break;
}
}
}
}
}
}
结果及分析
【%6】及其低效的一个算法。
思路二
之前看到过一个很巧妙的办法,不过后来忘了,因为题目中要求不能新建一个数组,只能在这一个数组上操作。其实可以对数组进行遍历,同时设置一个标志位,如果遍历到的元素为0,则标志位不变。如果遍历到的元素非0,则把元素赋值到标志位对应的数组中,同时标志位+1,我觉得还是代码能够说清楚。
代码
public class Solution {
public void moveZeroes(int[] nums) {
int index = 0;
for(int i = 0;i < nums.length;i++){
if(nums[i] != 0){
nums[index] = nums[i];
index++;
}
}
for(;index < nums.length;index++){
nums[index] = 0;
}
}
}
结果及分析
【You are here!
Your runtime beats 22.98% of javasubmissions.】O(n)的时间复杂度,感觉是最优的了。
二刷 思路三
最好不要在if中嵌套if,不专业。所以对思路进行改进,如果尾指针的元素不为0,则跳过,包括数组一开始就有一堆非0的数字,当第一次出现0的时候,头指针继续向前走,尾指针不动,当头指针遇到非0的元素,头尾指针交换数组的内容同时尾指针向前移动一次。
代码
public class Solution {
public void moveZeroes(int[] nums) {
if(nums == null || nums.length <= 0)
return;
for(int head = 0,tail = 0;head < nums.length;head++){
if(nums[tail] != 0){
tail++;
continue;
}
if(nums[head] != 0){
nums[tail] = nums[head];
nums[head] = 0;
tail++;
}
}
}
}