持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第19天,点击查看活动详情
一、题目
LeetCode 对角线遍历
给你一个大小为 m x n 的矩阵 mat ,请以对角线遍历的顺序,用一个数组返回这个矩阵中的所有元素。
示例 1:
输入: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]
提示:
m == mat.length
n == mat[i].length
1 <= m, n <= 104
1 <= m * n <= 104
-105 <= mat[i][j] <= 105
二、题解
方法一
简单直接的就是根据题目的要求按顺序来遍历数组即可。可以根据题目的示例寻找规律,按对角线遍历的方向,要么是往右上角方向遍历下一个元素,要么就是往左下角遍历下一个元素。初始的就是从右上角方向遍历元素,然后遇到边界就换从左下角遍历元素,如此往复直到遍历结束。然后需要遍历的方向次数就是矩阵的两边边长相加再减一即m + n - 1次,所以对于每一次的对角线遍历,奇数次的时候方向是为往右上角的,偶数次的时候方法就是往左下角的。对于往右上角的方向遍历的话,下一个元素是在上一行下一列的位置,就是需要将行下标减一、列下标加一,需要注意不要超边界;而对于往左下角的方向遍历的话,下一个元素是在下一行上一列的位置,即需要将行下标加一、列下标减一,也需要注意边界。而每一次遇到边界的时候就需要转换方向,转换方向的时候就需要从另外一个起点开始按方向来遍历,当是奇数次方向的时候,遍历的起点就是最左下角;当是偶数次方向的时候,遍历的起点就是最右上角。
三、代码
方法一 Java代码
class Solution {
public int[] findDiagonalOrder(int[][] mat) {
int m = mat.length;
int n = mat[0].length;
int[] res = new int[m * n];
int index = 0;
for (int i = 0; i < m + n - 1; i++) {
if (i % 2 == 1) {
int y = Math.min(i, n - 1);
int x = i - y;
while (x < m && y >= 0) {
res[index++] = mat[x++][y--];
}
} else {
int x = Math.min(i, m - 1);
int y = i - x;
while (y < n && x >= 0) {
res[index++] = mat[x--][y++];
}
}
}
return res;
}
}
时间复杂度:O(n),需要遍历一次数组的所有元素。
空间复杂度:O(1),只需要使用常数的空间。