對角線遍歷

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章