力扣刷题:蜗牛函数

184 阅读2分钟

前言:锻炼自己的思想,规范自己的编程思路。

问题:

请你编写一段代码为所有数组实现 snail(rowsCount,colsCount) 方法,该方法将 1D 数组转换为以蜗牛排序的模式的 2D 数组。无效的输入值应该输出一个空数组。当 rowsCount * colsCount !==nums.length 时。这个输入被认为是无效的。

image-20230613230041822.png

蜗牛排序从左上角的单元格开始,从当前数组的第一个值开始。然后,它从上到下遍历第一列,接着移动到右边的下一列,并从下到上遍历它。将这种模式持续下去,每列交替变换遍历方向,直到覆盖整个数组。例如,当给定输入数组 [19, 10, 3, 7, 9, 8, 5, 2, 1, 17, 16, 14, 12, 18, 6, 13, 11, 20, 4, 15] ,当 rowsCount = 5 且 colsCount = 4 时,需要输出矩阵如下图所示。注意,矩阵沿箭头方向对应于原数组中数字的顺序。

示例:

输入:
nums = [19, 10, 3, 7, 9, 8, 5, 2, 1, 17, 16, 14, 12, 18, 6, 13, 11, 20, 4, 15]
rowsCount = 5
colsCount = 4
输出:
[
 [19,17,16,15],
 [10,1,14,4],
 [3,2,12,20],
 [7,5,18,11],
 [9,8,6,13]
]

思路:

这个函数接受两个参数:rowsCount 和 colsCount,分别表示所需的二维数组的行数和列数。

首先,该函数检查输入是否有效:

如果数组长度为零,或者rowsCount * colsCount 不等于数组长度,则返回一个空数组。

如果rowsCount 等于 1,则返回一个包含原始数组的新数组。函数创建一个新的二维数组 res,并初始化其行数为rowsCount。然后,函数使用一个循环来遍历原始数组中的每个元素。在每次迭代中,它首先检查当前行号row 是否超出了临界值(即是否等于 rowsCount 或 -1)。

如果是,则将行号调整回有效范围内,并将列号 col 增加 1。同时,它还会切换布尔变量 isReverse 的值,以便在正序和逆序之间切换。

最后,根据 isReverse 的值,该方法将当前元素放入二维数组的相应位置,并相应地更新行号。

当循环结束时,该方法返回填充好的二维数组。

基于上述思考,代码如下:

/**
 * @param {number} rowsCount
 * @param {number} colsCount
 * @return {Array<Array<number>>}
 */
Array.prototype.snail = function(rowsCount, colsCount) {
    if (!this.length || rowsCount * colsCount !== this.length) {
        return [];
    }
    if (rowsCount === 1) {
        return [this];
    }
    //创建二维数组
    let res = new Array()
    for (let i = 0; i < rowsCount; i++) {
        res[i] = new Array()
    }
    let row = 0, col = 0;
    let isReverse = false;
    // 放入数据
    for (let i = 0; i < this.length; i++) {
        if (row === rowsCount || row === -1) { // 判断是否超出临界值
            row = isReverse? ++row : --row;
            isReverse = !isReverse; //转换正逆序方向
            col++;
        }
        //console.log(res)
        if (!isReverse) {
            res[row++][col] = this[i]
        } else {
            res[row--][col] = this[i]
        }
    }
    return res;
}

执行结果如下图:

image-20230613230014946.png