0
点赞
收藏
分享

微信扫一扫

javaScript数组-(进阶算法)-移动零


移动零

给定一个数组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);
};

  1. 声明函数:
  • var moveZeroes = function(nums) 定义了一个名为 moveZeroes 的变量,并将其赋值为一个匿名函数。这个函数接受一个参数 nums,即待处理的数组。
  1. 使用 sort() 方法:
  • 函数体内部仅有一行代码:nums.sort((a, b) => b ? 0 : -1);
  • sort() 是 JavaScript 数组的一个原生方法,用于对数组元素进行排序。它通常接受一个可选的比较函数作为参数,该函数定义了元素之间如何进行比较以确定它们的相对顺序。详细用法可参考《javascript深度理解数组的sort()排序》
  1. 自定义比较函数:
  • (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),并不适合于简单地移动特定元素的任务。在实际应用中,使用上面的双指针法或其他更直接的遍历交换方法可能更为高效。


举报

相关推荐

0 条评论