给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示。
示例:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,4,7,5,3,6,8,9]
解释:
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/diagonal-traverse
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
对角线的特征
我们首先先忽略对角线的方向,观察对角线的数量。
注意到
关注第一行,发现第一行的每一项正好对应一条对角线。
关注最后一列,发现最后一列的每一项正好对应一条对角线。
前两者重复的即只有包含右上顶点的那一条,而除了那一条加起来就是全部的对角线。
所以对角线的总数为 行数 + 列数 - 1
观察对角线的方向,注意到对角线向右上或者向左下是交替进行的。
所以可以通过对对角线排序,通过序号判断向上或者向下。
我们设行数为M,列数为N,令最左上角的为第0条对角线,最右下的为第M+N-2条对角线。则当对角线的序号为偶数时,对角线是向右上的。称对角线为curve_line。
数据行列的特征
在一条对角线上,行和列的序号加起来是恒定的,因为如果行+1了则列必定-1。。
如果找到了行(或列)的起始与结束范围,列的就迎刃而解,这题就好做了。
行的起始
在对角线小于等于列数的时候,观察到始终是从第0行开始。
超过了列数后,每超过一条,起始行数也要加一。
超过后的起始即 curve_line + 1 - N
注意对角线是从0开始计数的,而行数是实打实的。
行的结束
从最后一行看,当对角线数大于等于行数时,观察到始终到第M行结束,即索引为M-1。
当对角线小于行数时,观察到每少一条,结束行数也-1。
对角线小于行数的结束点是 curve_line
总思路
处理 matrix 为空的特殊情况
计算M,N
生成新的列表
按照对角线进行遍历,按照之前总结的规律添加到列表当中。
作者:jimmy00745
链接:https://leetcode-cn.com/problems/two-sum/solution/dui-jiao-xian-bian-li-gui-lu-xiang-xi-jie-xi-by-ji/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#根据行
class Solution:
def findDiagonalOrder(self, matrix):
if len(matrix) == 0:
return []
M, N, result = len(matrix), len(matrix[0]), []
for curve_line in range(M + N - 1):
#起始行,curve_line从0开始
if curve_line <= N -1:
row_begin = 0
else:
row_begin = curve_line + 1 - N
#结束行:最后的M条对角线的结束行均为M-1,则curve_line>=M+N-1-N=>curve_line>=M-1
if curve_line + 1 >= M:
row_end = M - 1
else:
row_end =curve_line
if curve_line % 2 == 1:
#range函数生成列表不包含最后需要单独处理
#奇数条对角线,向左下
for i in range(row_begin,row_end + 1):
result.append(matrix[i][curve_line - i])
else:
#偶数行对角线,向右上
for i in range(row_end,row_begin - 1,-1):
result.append(matrix[i][curve_line - i])
return result
#根据列
class Solution:
def findDiagonalOrder(self, matrix):
if len(matrix) == 0:
return []
M, N, result = len(matrix), len(matrix[0]), []
for curve_line in range(M + N - 1):
#起始行,curve_line从0开始
if curve_line <= M -1:
col_begin = 0
else:
col_begin = curve_line + 1 - M
#结束行:最后的N条对角线的结束行均为N-1
if curve_line + 1 > N:
col_end = N - 1
else:
col_end =curve_line
if curve_line %2 == 1:
#range函数生成列表不包含最后需要单独处理
#奇数条对角线,向左下
for i in range(col_end,col_begin - 1,-1):
result.append(matrix[curve_line-i][i])
else:
#偶数行对角线,向右上
for i in range(col_begin,col_end + 1):
result.append(matrix[curve_line-i][i])
return result
# if __name__=='__main__':
m = Solution()
matrix=[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
print(m.findDiagonalOrder(matrix))