移动零
给定一个数组nums
,编写一个函数将所有0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意,必须在不复制数组的情况下原地对数组进行操作。
示例1:
输入:nums = [0,1,0,3,12]
输出:[1,3,12,0,0]
示例2:
输入:nums = [0]
输出:[0]
code方式1(遍历优化)
let arr = [0, 1, 0, 3, 12];
function moveZeroes(nums) {
let len = nums.length;
let index = 0;
for(let i = 0; i < len; i++){
if(nums[i]){
if(index == i){
index++
}else{
nums[index++] = nums[i];
nums[i] = 0;
}
}
}
return nums;
}
console.log(moveZeroes(arr));
解题思路一:
// 定义一个名为moveZeroes的函数,接收一个数组参数nums
function moveZeroes(nums) {
// 获取输入数组nums的长度
let len = nums.length;
// 初始化变量index为0,用于记录非零元素在新数组中的插入位置
let index = 0;
// 遍历输入数组nums
for (let i = 0; i < len; i++) {
// 检查当前元素是否为非零值
if (nums[i]) {
// 情况1:若当前索引等于index,说明非零元素已在正确位置,只需递增index
if (index == i) {
index++;
}
// 情况2:若当前索引不等于index,需要将非零元素移到index处,并将原位置置零
else {
nums[index++] = nums[i]; // 移动非零元素并递增index
nums[i] = 0; // 将原位置置零
}
}
}
// 遍历结束后,返回处理后的数组nums,其中零元素已移动至末尾,非零元素顺序不变
return nums;
}
code 2 (遍历)
是code1方式的原版,优点(顺势思考,好理解)
let nums = [0,2,0,4,0,6,0,8,0,10]
function moveZeroes(nums) {
let index = 0;
for(let i = 0;i<nums.length;i++){
if(nums[i]!=0){
nums[index++] = nums[i]
}
}
console.log(index);
for(let i = index;i<nums.length;i++){
nums[i] = 0
}
return nums;
}
console.log(moveZeroes(nums));
解释
// 定义一个数组nums,包含一系列偶数和零
let nums = [0,2,0,4,0,6,0,8,0,10]
/**
* 将数组中的所有零移动到末尾
* @param {Array} nums - 输入的包含数字的数组
* @return {Array} - 移动零后的数组
*/
function moveZeroes(nums) {
let index = 0; // 初始化一个索引,用于记录非零元素应该放置的位置
// 遍历数组,将非零元素依次放到数组的前部
for(let i = 0;i<nums.length;i++){
if(nums[i]!=0){
nums[index++] = nums[i]
}
}
// 将index之后的位置全部填充为零
for(let i = index;i<nums.length;i++){
nums[i] = 0
}
return nums; // 返回移动零后的数组
}
// 打印移动零后的数组
console.log(moveZeroes(nums));
code 3,双指针写法
let nums = [0,2,0,0,4,0,6,0,0,10]
function moveZeroes(nums) {
let left = 0,right=0;
while(right<nums.length){
if(nums[right]!==0){
[nums[left],nums[right]]=[nums[right],nums[left]]
left++
}
right++
}
return nums
}
console.log(moveZeroes(nums));
代码解释
// 定义一个数组nums,其中包含一系列偶数和零
let nums = [0,2,0,4,0,6,0,8,0,10];
/**
* 将数组中所有的零移动到末尾
* @param {Array} nums - 输入的包含数字的数组
* @return {Array} - 移动零后的数组
*/
function moveZeroes(nums) {
let left = 0, right = 0; // 初始化左右指针,left指向非零元素应放置位置,right用于遍历数组
// 使用双指针法遍历数组,当遇到非零元素时与left所指位置交换
while (right < nums.length) {
if (nums[right] !== 0) {
[nums[left], nums[right]] = [nums[right], nums[left]]; // 交换left与right位置的元素
left++; // 左指针向右移动,准备处理下一个非零元素
}
right++; // 右指针继续向右移动,遍历下一个数组元素
}
return nums; // 返回移动零后的数组
}
// 打印移动零后的数组
console.log(moveZeroes(nums));
var moveZeroes = function(nums) {
nums.sort((a, b) => b ? 0 : -1);
};
Code4 (学习)
这段代码定义了一个名为 moveZeroes 的 JavaScript 函数,其作用是将给定数组 nums 中的所有零元素移动到数组的末尾。该函数实现方式非常简短,使用了数组的 sort() 方法并传入一个自定义的比较函数作为参数。以下是详细的解释:
var moveZeroes = function(nums) {
nums.sort((a, b) => b ? 0 : -1);
};
- 声明函数:
var moveZeroes = function(nums)
定义了一个名为moveZeroes
的变量,并将其赋值为一个匿名函数。这个函数接受一个参数nums
,即待处理的数组。
- 使用
sort()
方法:
- 函数体内部仅有一行代码:
nums.sort((a, b) => b ? 0 : -1);
sort()
是 JavaScript 数组的一个原生方法,用于对数组元素进行排序。它通常接受一个可选的比较函数作为参数,该函数定义了元素之间如何进行比较以确定它们的相对顺序。详细用法可参考《javascript深度理解数组的sort()排序》
- 自定义比较函数:
(a, b) => b ? 0 : -1
是一个箭头函数,用于作为sort()
方法的比较函数。它接收两个参数a
和b
,分别代表正在比较的数组元素。- 这个箭头函数的逻辑如下:
b ? 0 : -1
使用了三元运算符。如果条件b
为真(非零),则返回0
;否则返回-1
。
当b
非零(即 b 是一个非零数值)时,比较函数返回 0,表示 a 和 b 相等,sort() 方法不会改变它们的相对顺序。
当b
为零时,比较函数返回-1
,表示a
应该排在b
之前。由于sort()
默认为升序排列,返回-1
会将a
向数组的头部移动,而b
(零值)则向后移。
综上所述,这段代码通过利用 sort()
方法及自定义比较函数,实现了将数组 nums
中的所有零元素向数组末尾移动的效果。尽管这种实现方式简洁,但需要注意的是,它依赖于sort()
方法的稳定性(即相等元素的原始顺序保持不变),且对于大型数组可能会有性能上的考量,因为 sort()
方法通常采用一种通用排序算法(如快速排序、归并排序等),其时间复杂度为 O(n log n)
,并不适合于简单地移动特定元素的任务。在实际应用中,使用上面的双指针法或其他更直接的遍历交换方法可能更为高效。