一、 题目
1. 题目描述
给你一个大小为 m x n
的矩阵 mat
,请以对角线遍历的顺序,用一个数组返回这个矩阵中的所有元素。
示例 1:
![](https://i-blog.csdnimg.cn/blog_migrate/3ef22280245c8c416fd42a86326d2ffe.jpeg)
输入: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
Related Topics
- 数组
- 矩阵
- 模拟
- 👍 330
- 👎 0
2. 原题链接
链接: 498. 对角线遍历
二、 解题报告
1. 思路分析
- 下标直接模拟,我们发现一共有m+n-1条对角线,处理每条对角线时计算初始端点的i,j,然后让他们移动即可。
- 下标搜索:
- 从(0,0)开始,方向一共有
右上
、左下
两个方向; - 向右上搜索若出界:坐标向下移动1格,方向调转,继续搜索。
- 向左下收缩若出界:坐标向右移动1格,方向调转,继续搜索。
- 直到到达(m-1,n-1)。
- 从(0,0)开始,方向一共有
2. 复杂度分析
时间复杂度O(nm)
3. 代码实现
下标模拟
。
class Solution:
def findDiagonalOrder(self, mat: List[List[int]]) -> List[int]:
m,n = len(mat),len(mat[0])
ans = []
for k in range(m+n-1): # 处理第k条对角线
if k&1 == 0:
i = k if k < m else m-1
j = 0 if k < m else k-m+1
while i>=0 and j < n:
ans.append(mat[i][j])
i -= 1
j += 1
else:
i = 0 if k < n else k - n + 1
j = k if k < n else n-1
while i<m and j>=0:
ans.append(mat[i][j])
i += 1
j -= 1
return ans
搜索
。
class Solution:
def findDiagonalOrder(self, mat: List[List[int]]) -> List[int]:
m,n = len(mat),len(mat[0])
ans = []
dirs = [(-1,1),(1,-1)] # 向右上,向左下
change = [(1,0),(0,1)] # 向下,向右
d = 0
x,y = 0,0
def in_bound(x,y):
return 0<=x<m and 0<=y<n
while not (x == m-1 and y == n-1):
if in_bound(x,y):
ans.append(mat[x][y])
x += dirs[d][0]
y += dirs[d][1]
if not in_bound(x,y):
x += change[d][0]
y += change[d][1]
d ^=1
ans.append( mat[m-1][n-1])
return ans
三、 本题小结
- 几乎是对角线搜索的模板