对角线遍历

给定一个含有 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))

 

你可能感兴趣的:(python)