算法--螺旋矩阵

64 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情

题目

leetcode 54. 螺旋矩阵 难度:中等

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

示例 1:

image.png

输入: matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出: [1,2,3,6,9,8,7,4,5]

示例 2:

image.png

输入: matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]

提示:

m == matrix.length n == matrix[i].length 1 <= m, n <= 10 -100 <= matrix[i][j] <= 100

题解

题目的意思是让我们根据矩阵来然后顺时针输出里面的数字。
我们就可以标记顺时针旋转的4个方向:

  • 0代表向右
  • 1代表向下
  • 2代表向左
  • 3代表向上

建立二维坐标系,通过坐标和方向来完成输出。值得关注的是如何控制坐标的移动,移动的节点如何控制。

/**
 * @param {number[][]} matrix
 * @return {number[]}
 */
var spiralOrder = function (matrix) {
    let row = matrix.length;
    let column = matrix[0].length;
    const res = [];
    const all = row * column;

    let rowS = 0;
    let columnS = 0;
    let i = 0;
    let j = 0;
    let duration = 0;
    while (res.length < all) {
        res.push(matrix[i][j]);

        if (duration === 0) {
            j++;
            if (j === column) {
                duration = (duration + 1) % 4;
                rowS++;
                i++;
                j--;
            }
        } else if (duration === 1) {
            i++;
            if (i === row) {
                duration = (duration + 1) % 4;
                row--;
                j--;
                i--;
            }
        } else if (duration === 2) {
            j--;
            if (j < columnS) {
                duration = (duration + 1) % 4;
                columnS++;
                i--;
                j++;
            }
        } else if (duration === 3) {
            i--;
            if (i < rowS) {
                duration = (duration + 1) % 4;
                column--;
                j++;
                i++;
            }
        }
    }
    return res
};

代码详解

row 代表的是矩阵的行数,column代表的是矩阵的列数,res代表的是输出数组,all代表总个数,rowScolunmS表示坐标后退的极限。i,j,duration代表坐标点和方向。

我们只需要循环出矩阵总数字个数的结果即可

  • 当方向向右的时候每次移动的是j坐标,当j坐标到达极限时(column)方向就要变成向下,此时的最上面外圈已经循环完成rowS++,控制i坐标移动i++,j坐标此时已经溢出所以j--还原一位。
  • 当方向向下的时候每次移动的是i坐标,当i坐标到达极限时(row)方向就要变成向左,此时的最右边外圈已经循环完成row--,控制j坐标移动j--,i坐标此时已经溢出所以i--还原一位。
  • 当方向向左的时候每次移动的是j坐标,当j坐标到达极限时(cloumnS)方向就要变成向上,此时的最下面外圈已经循环完成column--,控制i坐标移动i--,j坐标此时已经溢出所以j++还原一位。
  • 当方向向上的时候每次移动的是i坐标,当j坐标到达极限时(rowS)方向就要变成向右,此时的最左边外圈已经循环完成columnS++,控制j坐标移动j++,i坐标此时已经溢出所以i++还原一位。