『JavaScript』二维数组螺旋扁平化

本文介绍了如何使用JavaScript对二维数组进行顺时针和逆时针螺旋扁平化处理,通过步骤分析和示例代码展示了如何将给定的二维数组转化为一维数组,适用于解决蓝桥杯Web赛项中的特定问题。
摘要由CSDN通过智能技术生成

『JavaScript』二维数组螺旋扁平化

1. 问题引入

在准备蓝桥杯 Web 赛项的时候,遇到过一个问题:

公主被关在地图中央,骑⼠最开始在⼆维地图 [0, 0] 的位置。补全 mazePath 函数,将起点到终点顺时针经过的每个元素(即 class 包含 box ) data-index 属性值依次保存在数组中并返回。

恶龙与公主
来源:《第十四届蓝桥杯国赛(Web 应用开发) 大学组 - “恶龙与公主”》

下图是游戏的迷宫界面,意思是我们需要把一个 5 * 5 的二维数组按照顺时针的顺序转化为一维数组。

游戏界面
现在,我们要开发一个通用方法,将 row * column 的二维数组(矩阵)按规则转化为一维数组。暂且将这个方法称为 二维数组螺旋扁平化,下面将介绍二维数组的 顺时针螺旋扁平化逆时针螺旋扁平化

2. 步骤分析

我们对这个 5*5 的矩阵进行顺时针分析。

首先要把第一排的数组全部添加到结果数组中,可以使用 shift() 方法取出第一行所有元素,添加到临时数组中。

步骤-1

现在假设第一行被删除了,剩下下面的 4*5 数组。再把每一行的最后一个元素 pop() 出来,添加到临时数组中。

步骤-2

紧接着还剩左下角 4*4 的数组,可以通过 pop() 取出最后一行所有元素;但是现在整个数组是顺序的,需要通过 reverse() 把最后一行逆序,添加到临时数组中。

步骤-3

最后就是倒序遍历数组,依次 unshift() 每一行的第一个元素,添加到临时数组中。

步骤-4

还剩下中间的 3*3 数组,再顺序执行前面的步骤,直到数组中没有元素。

3. 生成测试用例

这是题目中给定的测试用例:

const array1 = [
    ['start', 1, 2, 3, 4],
    [5, 6, 7, 8, 9],
    [10, 11, 'end', 13, 14],
    [15, 16, 17, 18, 19],
    [20, 21, 22, 23, 24]
];

当然我们也可以自己生成测试用例:

/**
 * 生成一个指定行数和列数的二维数组,数组元素从1开始顺序递增
 * 
 * @param {number} rows 行数
 * @param {number} columns 列数
 * @returns {number[][]} 二维数组
 */
function generateNumberMatrix(rows, columns) {
    const result = [];
    // 扁平化数组长度
    const length = rows * columns;
    // 生成矩阵
    for (let i = 0; i < length; i++) {
        // 计算行下标
        const rowIndex = Math.floor(i / columns);
        // 创建行
        if (!result?.[rowIndex]) result.push([]);
        // 在行中添加元素
        result[rowIndex].push(i + 1)
    }
    return result;
}

4. 顺时针螺旋扁平化

/**
 * 将二维数组顺时针展开为一维数组
 * 
 * @param {Array<Array>} arr 二维数组
 * @returns {Array} 一维数组
 */
function clockwiseSpiralFlatten(arr) {
    const result = [];

    while (arr.length) {
        // 从左到右
        result.push(...arr.shift());
        // 从上到下
        for (const row of arr) {
            if (row.length) result.push(row.pop());
        }
        // 从右到左
        if (arr.length) result.push(...arr.pop().reverse());
        // 从下到上
        for (let i = arr.length - 1; i >= 0; i--) {
            if (arr[i].length) result.push(arr[i].shift());
        }
    }

    return result;
}

测试:

// 题目用例
console.log(clockwiseSpiralFlatten(array1));
// 6*3 矩阵
const array2 = generateNumberMatrix(6, 3);
console.log(clockwiseSpiralFlatten(array2));

// 测试结果
// ['start', 1, 2, 3, 4, 9, 14, 19, 24, 23, 22, 21, 20, 15, 10, 5, 6, 7, 8, 13, 18, 17, 16, 11, 'end']
// [1, 2, 3, 6, 9, 12, 15, 18, 17, 16, 13, 10, 7, 4, 5, 8, 11, 14]

在线运行:

5. 逆时针螺旋扁平化

/**
 * 将二维数组逆时针展开为一维数组
 * 
 * @param {Array<Array>} arr 二维数组
 * @returns {Array} 一维数组
 */
function counterClockwiseSpiralFlatten(arr) {
    const result = [];

    while (arr.length) {
        // 从上到下
        for (const row of arr) {
            if (row.length) result.push(row.shift());
        }
        // 从左到右
        result.push(...arr.pop());
        // 从下到上
        for (let i = arr.length - 1; i >= 0; i--) {
            if (arr[i].length) result.push(arr[i].pop());
        }
        // 从右到左
        if (arr.length) result.push(...arr.shift().reverse());
    }

    return result;
}

测试:

// 题目用例
console.log(counterClockwiseSpiralFlatten(array1));
// 3*4 矩阵
const array2 = generateNumberMatrix(3, 4);
console.log(counterClockwiseSpiralFlatten(array2));

// 测试结果
// ['start', 5, 10, 15, 20, 21, 22, 23, 24, 19, 14, 9, 4, 3, 2, 1, 6, 11, 16, 17, 18, 13, 8, 7, 'end']
// [1, 5, 9, 10, 11, 12, 8, 4, 3, 2, 6, 7]

在线运行:

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值