题目描述:给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。
拿到这个题目的第一想法就是,从数组的末尾开始,将为0的元素移动栋数组的最后代码如下:
/**
* 从数组的末位开始,将为0的元素 移动到最末尾
* @param nums 传入参数
*/
private static void moveArray(int[] nums) {
if (nums == null || nums.length == 0) {
return ;
}
for (int i = nums.length - 1; i >= 0; i--) {
if (nums[i] == 0) {
for (int j = i; j < nums.length - 1; j++) {
int temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
}
}
提交LeetCode运行结果如下:
![_V3T]R%@SWP1EK0CUS~)F33.png](https://upload-images.jianshu.io/upload_images/8551754-37fb3db48f4ac545.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
感觉在将为0元素移动到数组最末做了大量无用操作,遂改进一番。
先定义m,n两个数,m为非0元素的长度,n为当前循环到的数组长度,代码如下:
private static void moveArray0(int[] nums) {
if (nums == null || nums.length == 0) {
return ;
}
//定义 定义m,n两个数,m为非0元素的长度,n为当前循环到的数组长度
int m = 0,n = 0;
for (int i = 0;i < nums.length;i++){
if (nums[i] == 0){
//记录当前循环到的数组长度
n++;
}else {
//若数组当前元素非0,将数组中m位置 变成当前非0元素
if (n - m > 0){
int x = nums[m];
nums[m] = nums[i];
nums[i] = x;
}
//记录当前循环到的数组长度
n++;
//非0数组长度
m++;
}
}
}
提交LeetCode运行情况如下:
[图片上传失败...(image-74420-1556175387692)]
分析 这种方式 对整个数组只是循环了一次,对只是为0的元素进行了对换,效率大大提升。