题目描述
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:
输入: nums = [0]
输出: [0]
提示:
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
进阶:你能尽量减少完成的操作次数吗?
解法1:先位移再补0
/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var moveZeroes = function(nums) {
let data={}
let count=0;
//记录每个索引位置前有几个0
for(let i=0;i<nums.length;i++){
if(nums[i]==0){
count++;
}
data[i]=count;
}
//将当前位置及前面0的个数进行位移
for(let i=0;i<nums.length;i++){
if(nums[i]!=0){
nums[i-data[i]]=nums[i];
}
}
// //位移最后将对应个数位置置0
for(let i=1;i<=data[nums.length-1];i++){
nums[nums.length-i]=0;
}
};
执行情况
解法2:记录0所在位置,后续非0与0所在位置进行交换。
/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var moveZeroes = function(nums) {
let j=[];
for(let i=0;i<nums.length;i++){
if(nums[i]==0){
j.push(i);
}
if(nums[i]!=0&&j.length>0){
nums[j.shift()]=nums[i];
nums[i]=0;
j.push(i);
}
}
};
继续优化,减少数组的shift操作,增加一个变量,记录使用到了哪一个索引了。
/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var moveZeroes = function(nums) {
let j=[];
let objIndex=0;//该用哪一个索引了
for(let i=0;i<nums.length;i++){
if(nums[i]==0){
j.push(i);
}
else if(nums[i]!=0&&j.length>objIndex){
nums[j[objIndex++]]=nums[i];
nums[i]=0;
j.push(i);
}
}
};
执行情况
解法3: 滚雪球解法 0 会最终会和0挨在一起,记录挨在一起的0的个数 将非0提到0之前
/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var moveZeroes = function(nums) {
let zeroNum=0;
for(let i=0;i<nums.length;i++){
if(nums[i]==0){
zeroNum++;
}else{
if(zeroNum>0){
nums[i-zeroNum]=nums[i];
nums[i]=0;
}
}
}
};
执行情况:时间和内存综合下来还可以