题目:
给定一个数组nums,写一个函数,将数组中所有的0挪到数组的末尾,而维持其他所有非0元素的相对位置。
举例:
nums = [0, 1, 0, 3, 12],函数运行后结果为[1, 3, 12, 0, 0]
方法一:
新建一个数组,将非零元素提取出来,存入新建的数组,之后再按次序赋值给原数组,对于原数组之后的数组元素全部赋0。
时间复杂度:O(n)
空间复杂度:O(n)
方法一代码:
package com.haobi;
public class MoveZeros {
public static void main(String[] args) {
int[] arr = {0,1,0,3,12};
moveZeros(arr);
for(int a: arr) {
System.out.print(a+" ");
}
}
public static void moveZeros(int[] nums) {
//存储非零元素数组
int[] nonZero = new int[nums.length];
int count = 0;
//将非零元素按次序赋给nonZero数组
for(int i=0;i<nums.length;i++) {
if(nums[i] != 0) {
nonZero[count] = nums[i];
count++;
}
}
//将nonZero数组数据赋值给nums数组
for(int i=0;i<nonZero.length;i++) {
nums[i] = nonZero[i];
}
//将剩余长度位上的数组赋0
for(int i=nonZero.length;i<nums.length;i++) {
nums[i] = 0;
}
}
}
方法二:
不新建任何数组,没有使用任何辅助空间,只在原数组操作。用k[0…k)保存所有当前遍历过的非0元素。将非零元素按照顺序依次存进数组,对于k个长度及之后的数组元素全部赋0。
时间复杂度:O(n)
空间复杂度:O(1)
方法二代码:
package com.haobi;
public class MoveZeros1 {
public static void main(String[] args) {
int[] arr = {0,1,0,3,12};
moveZeros(arr);
for(int a: arr) {
System.out.print(a+" ");
}
}
public static void moveZeros(int[] nums) {
int k = 0;//nums中,[0...k)的元素均为非0元素
//遍历到第i个元素后,保证[0...k)的元素均为非0元素
//遍历完成后,所有的非0元素都按照顺序排列在[0...k)中
for(int i=0;i<nums.length;i++) {
if(nums[i] != 0) {
nums[k++] = nums[i];
}
}
//将nums剩余的位置赋0
for(int i=k;i<nums.length;i++) {
nums[i] = 0;
}
}
}
方法三:
在数组内,交换非零元素与0元素。因此不需要额外的赋值操作。
时间复杂度:O(n)
空间复杂度:O(1)
方法三代码:
package com.haobi;
public class MoveZeros2 {
public static void main(String[] args) {
int[] arr = {0,1,0,3,12};
moveZeros(arr);
for(int a: arr) {
System.out.print(a+" ");
}
}
public static void moveZeros(int[] nums) {
int k = 0;//nums中,[0...k)的元素均为非0元素
//遍历到第i个元素后,保证[0...k)的元素均为非0元素
//遍历完成后,所有的非0元素都按照顺序排列在[0...k)中
//同时,[k...i]为0
for(int i=0;i<nums.length;i++) {
if(nums[i] != 0) {
if(i != k) {
//交换0元素与非0元素
int temp = nums[k];
nums[k++] = nums[i];
nums[i] = temp;
}else {
k++;
}
}
}
}
}