leetcode 对角线遍历 中等

leetcode 对角线遍历 中等

 

 

首先可以确定,每一条对角线其 i + j 的值都是定值,所以可以枚举这个定值;这个定值的范围显然是 [0, n - 1 + m - 1)

然后就是,如果对角线的值为偶数,那么就是从下往上遍历,否则就是从上往下;

对于从上往下的情况,最简单的就是其 i = 0,然后 i 一直递增即可,但显然在后半部分对角线,i 的初始值不是 0,应该是 (i + j) - (m - 1). 但实际上根本不需要区分前后半部分对角线,i 的初始值就是 max(0, (i + j) - (m - 1)).....然后就是 i 的最大值,很显然,后半部分对角线 i 的最大值为 n,而前半部分 i 的最大值为 (i + j).... 即 i 的上限为 min(i + j, n - 1)

对于从下往上的情况与上类似

class Solution {
public:
    vector<int> findDiagonalOrder(vector<vector<int>>& mat) {
        if(mat.empty() || mat[0].empty()) return {};
        int n = mat.size(), m = mat[0].size();
        vector<int> ret;
        ret.reserve(n + m - 2);
        for(int i = 0; i < n + m - 1; ++ i) {   // i 表示 原矩阵 行+列 的值, 因为每一条对角线 行+列 的固定
            if(i & 1) {     // 奇数, 从上至下
                for(int j = max(0, i - (m - 1)); j < min(i + 1, n); ++ j) {   // j 表示行
                    int k = i - j;      // k 表示列
                    ret.emplace_back(mat[j][k]);
                }
            } else {    // 偶数, 从下至上
                for(int k = max(0, i - (n - 1)); k < min(i + 1, m); ++ k) {   // k 表示列
                    int j = i - k;
                    ret.emplace_back(mat[j][k]);
                }
            }
        }
        return ret;
    }
};

 但其实对于第二重 for 循环来说,可以不用算 for 的上界,因为如果 int k = i - j, k < 0 直接 break 即可。

上一篇:2021.09.24 - 079.01 矩阵


下一篇:Leetcode刷题100天—566. 重塑矩阵(数组)—day25