数组项移位算法

109 阅读2分钟

背景

开发中遇到一个需求,有三个设置项通过输入1-3进行排序,其中一个配置项输入1-3中某个数字后,其他两项需要依次补位。

const arr = [1, 2, 3]
如:第二项输入:1, arr[1] = 1;
则其余两项补位2、3, 则第一项是 2:arr[0] = 3;第三项是2: arr[2] = 2;
结果: arr = [3, 1, 2]

解决思路

  • 开始想快速实现,就写死了可能出现的三种排列方式,然后通过输入的第几项与值去进行匹配获取排列的结果;如下:
const arrMap = [
  [1, 2, 3],
  [3, 1, 2],
  [2, 3, 1]
] // 1-3,组成的三种排列组合
const index = 0 // 输入第 n 项,即数组下标
const value = 1 // 输入第 n 项的值
const newArr = arrMap.find((item) => item[index] === value)
console.log('%c [ newArr ]-1696', 'font-size:13px; background:pink; color:#bf2c9f;', newArr)

image.png

  • 或者通过循环,先计算出移位次数,再循环原数组处理进行移位赋值。
const arr = [1, 2, 3]
const index = 2 // 输入第 n 项,即数组下标
const value = 2 // 输入第 n 项的值
const diff = Math.abs(arr.indexOf(value) - index) // 移动的次数 = 输入的位置 - 该值的最初位置
const newArr = arr
for (let i = 0; i < diff; i++) { // 循环次数
    let temp = newArr[newArr.length - 1] // 下一个位置的被赋值的值,默认第一个去最后一项
    for (let j = 0; j < newArr.length; j++) {
      const current = newArr[j] // 记录赋值位置的值
      newArr[j] = temp
      temp = current // 下次位置赋值的值
    }
}
console.log('%c [ newArr - 结果:]-1685', 'font-size:13px; background:pink; color:#bf2c9f;', newArr)

image.png

通过这样的方法可解决更多项的问题:

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
const index = 2 // 输入第 n 项,即数组下标
const value = 2 // 输入第 n 项的值
const diff = Math.abs(arr.indexOf(value) - index) // 移动的次数 = 输入的位置 - 该值的最初位置
const newArr = arr
for (let i = 0; i < diff; i++) { // 循环次数
    let temp = newArr[newArr.length - 1] // 下一个位置的被赋值的值,默认第一个去最后一项
    for (let j = 0; j < newArr.length; j++) {
      const current = newArr[j] // 记录赋值位置的值
      newArr[j] = temp
      temp = current // 下次位置赋值的值
    }
}
console.log('%c [ newArr - 结果:]-1685', 'font-size:13px; background:pink; color:#bf2c9f;', newArr)

image.png

  • 优化计算

力扣例题

力扣上面是 旋转数组:给定一个整数数组 nums,将数组中的元素向右轮转 k **个位置,其中 k **是非负数。

力扣官方题解如下:

var rotate = function(nums, k) {
    const n = nums.length;
    const newArr = new Array(n);
    for (let i = 0; i < n; ++i) {
        newArr[(i + k) % n] = nums[i];
    }
    for (let i = 0; i < n; ++i) {
        nums[i] = newArr[i];
    }
}