力扣498. 对角线遍历

153 阅读2分钟

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

力扣498. 对角线遍历

一、题目描述:

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

示例 1:

img

输入: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 <= 10^4

1 <= m * n <= 10^4

-10^5 <= mat[i] [j] <= 10^5

来源:力扣(LeetCode) 链接:leetcode.cn/problems/di… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思路分析:

这部分可以写写:

  1. 这道题考察了什么思想?你的思路是什么?

    我们可以了解如果矩阵的行为m,列为n,那么就可以计算出有m+n-1条对角线,接下来我们需要考虑的是对角线遍历的方向,如果当前遍历方向为左下到右上,那么相邻的两条对角线是右上到左下。

    我们设对角线的编号为i,其最小值是0,最大值为m+n-2.

    • 当 i 是偶数的时候,编号为i的对角线是从下往上遍历;
    • 当 i 是奇数的时候,编号为i的对角线是从上往下遍历;

    从左下到右上遍历时:起始点的x在第一列和最后一行,坐标为i和m - 1的最小值。 从右下到左上遍历时:起始点的y在最后一列和第一行,坐标为i和n - 1的最小值。

  2. 做题的时候是不是一次通过的,遇到了什么问题,需要注意什么细节?

    不是一次通过的,关系比较复杂,需要理清思路!

  3. 有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?

image.png

```
 class Solution:
     def findDiagonalOrder(self, mat: List[List[int]]) -> List[int]:
         result = []
         if len(mat) == 0:
             return result
 ​
         m = len(mat)
         n = len(mat[0])
         count = 0 # i+j==count
         while count < m + n - 1:
             # 向右上走,起点在左下
             if count % 2 == 0:
                 x = count if (count < m) else (m - 1)
                 y = count - x
                 while (x >= 0 and y <= n-1):
                     result.append(mat[x][y])
                     x -= 1
                     y += 1
             # 向左下走,起点在右上
             else:
                 y = count if (count < n) else (n - 1)
                 x = count - y
                 while (x <= m-1 and y >= 0):
                     result.append(mat[x][y])
                     x += 1
                     y -= 1
             count += 1
         return result
 ​
 作者:zzm-12
 链接:https://leetcode.cn/problems/diagonal-traverse/solution/shi-jian-kong-jian-ji-bai-100-er-wei-ju-surzy/
 来源:力扣(LeetCode)
 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
```

三、AC 代码:

 class Solution {
     public int[] findDiagonalOrder(int[][] mat) {
         int m = mat.length;
         int n = mat[0].length;
         int i = 0, j = 0; 
         boolean up = true; 
         int size = m * n;
         int[] result = new int[size];
         int cnt = 0;
         while (cnt < size) {
             result[cnt++] = mat[i][j];
 ​
             if (up) {
                 if (j == n - 1) {
                     i++;
                     up = !up;
                 } else if (i == 0) { 
                     j++;
                     up = !up;
                 } else {
                     i--;
                     j++;
                 }
             } else {
                 if (i == m - 1) { 
                     j++;
                     up = !up;
                 } else if (j == 0) {
                     i++;
                     up = !up;
                 } else {
                     i++;
                     j--;
                 }
             }
         }
         return result;
     }
 }

四、总结:

如果你还有更多的思考、分析、总结,通通都加上来吧~

498. 对角线遍历

此题关系比较复杂,需要理清思路!