题目:移动零
leetcode链接:初级算法 - 移动零
说明:给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
理解:
1、有一个既定数组,数组内元素应该至少有一个数字0
2、将所有0元素移动至末尾
思路:
1、将原数组所有数字0移除,然后统计出0的个数,之后在元素组末尾补上相应位数的0
2、使用双指针进行替换
3、变量替换
误区:
起初想过直接对原数组降序排,结果发现虽然0都在末尾,但是却打乱了非0元素在数组的顺序,导致一些测试实例无法通过
题解:
方案一、剔除数组内的0元素,然后在数组末尾相应位数补0
/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var moveZeroes = function(nums) {
var count = 0
for (var i = 0; i < nums.length; i++) {
if (nums[i] === 0) {
nums.splice(i, 1)
count++
i--
}
}
for (var i = 0; i < count; i++) {
nums.push(0)
}
return nums
};
方案二、双指针
/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var swap = function(nums, left, right) {
let temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
}
var moveZeroes = function(nums) {
let len = nums.length, left = 0, right = 0;
while (right < len) {
if (nums[right]) {
swap(nums, left, right);
left++;
}
right++;
}
return nums
};
方案三、
/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var moveZeroes = function(nums) {
let count = 0;
for (let i = 0; i < nums.length; i++) {
if (nums[i] == 0) {
count++;
continue;
}
nums[i - count] = nums[i];
}
while (count > 0) {
nums[nums.length-count] = 0;
count--;
}
};
方案四:
/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var moveZeroes = function(nums) {
let k = 0;
for (let i = 0; i < nums.length; i++) {
if (nums[i] == 0){
k++;
} else {
if(k > 0){
nums[i-k] = nums[i];
nums[i] = 0;
}
}
}
};
总结:
本篇对数组移动零的问题提供了几种解法,其中方案一时间复杂度太差了,远慢于其它几种解法,相比之下还是其它几种解法在时间复杂度上更好些,综合下来还是双指针的方式更好些。