給定一個含有 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))