力扣每日一题0614-498. 对角线遍历

127 阅读2分钟

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

给你一个大小为 m x n 的矩阵 mat ,请以对角线遍历的顺序,用一个数组返回这个矩阵中的所有元素。

示例 1:

image.png

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

示例 2:

输入:mat = [[1,2],[3,4]]
输出:[1,2,3,4]

直接模拟

根据题目要求,矩阵按照对角线进行遍历。设矩阵的行数为 mm, 矩阵的列数为 nn , 我们仔细观察对角线遍历的规律可以得到如下信息:

  • 一共有 m+n1m + n - 1 条对角线,相邻的对角线的遍历方向不同,当前遍历方向为从左下到右上,则紧挨着的下一条对角线遍历方向为从右上到左下;

  • 设对角线从上到下的编号为 i[0,m+n2]i \in [0, m + n - 2]:

    • ii 为偶数时,则第 ii 条对角线的走向是从下往上遍历;
    • ii 为奇数时,则第 ii 条对角线的走向是从上往下遍历;
  • 当第 ii 条对角线从下往上遍历时,每次行索引减 11,列索引加 11,直到矩阵的边缘为止:

    • i<mi<m 时,则此时对角线遍历的起点位置为 (i,0)(i,0)
    • imi \ge m 时,则此时对角线遍历的起点位置为 (m1,im+1)(m - 1, i - m + 1)
  • 当第 ii 条对角线从上往下遍历时,每次行索引加 11,列索引减 11,直到矩阵的边缘为止:

    • i<ni<n 时,则此时对角线遍历的起点位置为 (0,i)(0,i)
    • ini \ge n 时,则此时对角线遍历的起点位置为 (in+1,n1)(i - n + 1, n - 1)
var findDiagonalOrder = function(mat) {
    const m = mat.length;
    const n = mat[0].length;
    const res = new Array(m * n).fill(0);
    let pos = 0;
    for (let i = 0; i < m + n - 1; i++) {
        if (i % 2 === 1) {
            let x = i < n ? 0 : i - n + 1;
            let y = i < n ? i : n - 1;
            while (x < m && y >= 0) {
                res[pos] = mat[x][y];
                pos++;
                x++;
                y--;
            }
        } else {
            let x = i < m ? i : m - 1;
            let y = i < m ? 0 : i - m + 1;
            while (x >= 0 && y < n) {
                res[pos] = mat[x][y];
                pos++;
                x--;
                y++;
            }
        }
    }
    return res;
};