对角线遍历 Diagonal Traverse

目录

  • 问题描述
  • 对角线迭代和翻转
    • Python
    • C++

问题描述

Given a matrix of M x N elements (M rows, N columns), return all elements of the matrix in diagonal order as shown in the below image.

Example:
Input:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
Output: [1,2,4,7,5,3,6,8,9]
图解
图解

Note:The total number of elements of the given matrix will not exceed 10,000.

对角线迭代和翻转

算法:

  1. 初始化数组 result,用于存储最后结果。
  2. 使用一个外层循环遍历所有的对角线。第一行和最后一列的元素都是对角线的起点。
  3. 使用一个内层 while 循环遍历对角线上的所有元素。可以计算指定对角线上的元素数量,也可以简单迭代直到索引超出范围。
  4. 因为不知道每条对角线上的元素数量,需要为每条对角线分配一个列表或动态数组。但是同样也可以通过计算得到当前对角线上的元素数量。
  5. 对于奇数编号的对角线,只需要将迭代结果翻转再加入结果数组即可。
    对角线遍历 Diagonal Traverse_第1张图片

Python

class Solution:    
    def findDiagonalOrder(self, matrix: List[List[int]]) -> List[int]:        
        # Check for empty matrices
        if not matrix or not matrix[0]:
            return []        
        # Variables to track the size of the matrix
        N, M = len(matrix), len(matrix[0])        
        # The two arrays as explained in the algorithm
        result, intermediate = [], []        
        # We have to go over all the elements in the first
        # row and the last column to cover all possible diagonals
        for d in range(N + M - 1):            
            # Clear the intermediate array everytime we start
            # to process another diagonal
            intermediate.clear()            
            # We need to figure out the "head" of this diagonal
            # The elements in the first row and the last column
            # are the respective heads.
            r, c = 0 if d < M else d - M + 1, d if d < M else M - 1
            
            # Iterate until one of the indices goes out of scope
            # Take note of the index math to go down the diagonal
            while r < N and c > -1:
                intermediate.append(matrix[r][c])
                r += 1
                c -= 1            
            # Reverse even numbered diagonals. The
            # article says we have to reverse odd 
            # numbered articles but here, the numbering
            # is starting from 0 :P
            if d % 2 == 0:
                result.extend(intermediate[::-1])
            else:
                result.extend(intermediate)
        return result 

C++

class Solution {
public:
    vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
        if (matrix.size() == 0)
            return {};
        int M = matrix.size();
        int N = matrix[0].size();
        vector <int> result;
        for (int curve_line = 0 ; curve_line < (M + N - 1) ; curve_line ++){
            int row_begin = curve_line + 1 <= N ? 0 : curve_line + 1 - N;
            int row_end =  curve_line + 1 >= M ? M - 1 : curve_line;
            if (curve_line % 2 == 1){
                for (int i = row_begin ; i <= row_end ; i++)
                    result.push_back(matrix[i][curve_line - i]);
            }
            else{
                for (int i = row_end ; i >= row_begin ; i--)
                    result.push_back(matrix[i][curve_line - i]);
            }
        }
        return result;
    };
};

你可能感兴趣的:(数据结构与算法)