phpexcel遍历所有列_leetcode No.498 对角线遍历

31221d86d7a75f12c07c3d56de885bf3.png

既然已经说了这么多遍历,前中后,甚至还有垂序,我们再来看一道对角线遍历,不过不是二叉树的。

题目链接:

对角线遍历 - 力扣(LeetCode)​leetcode-cn.com
dfa4594b5e996d921e1f785c820ac125.png

题目描述:

给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示。

示例:

输入:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]

输出:  [1,2,4,7,5,3,6,8,9]

解释:

6f40250efd0f83edbcb18bf4b9903f86.png

说明:

  1. 给定矩阵中的元素总数不会超过 100000 。

解题思路:

如上面的解释图所示,其实就是“之字形”的数组对角线遍历,和二叉树的“之字形”遍历一样,我们肯定需要有两个方向,一个往右上,一个往左下。在不考虑边界情况的条件下,前者是所在行数减一,列数加一,而后者正好相反。

而如果遇到遍历到边界的情况,其实也很简单。如果是遇到的是右上方方向超出边界,就让所在行数不变,而列数加一。如果是左下方方向超出边界,就让所在列数不变,而行数加一。

具体实现的时候,迭代递归都可以。我自己是用递归实现的。

代码如下:

class Solution {
public:
    vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
        vector<int> res;
        if(matrix.empty()) return res;
        int m = matrix.size(), n = matrix[0].size();
        vector<pair<int, int>> dir({{-1, 1}, {1, -1}}); // 事先规定两个方向的移动参数
        DFS(matrix, res, 0, 0, m, n, dir, 0);
        return res;
    }
private:
    void DFS(vector<vector<int>>& matrix, vector<int>& res, int r, int c, int m, int n, vector<pair<int, int>>& dir, int d){
        if(res.size() == m * n) return;
        res.push_back(matrix[r][c]);
        int R = r + dir[d].first;
        int C = c + dir[d].second;
        if(R < 0 || C < 0 || R >= m || C >= n){ // 如果超出边界
            d = (d + 1) % 2; // 改变方向
            if(R < 0 || R >= m) R = r, C = c + 1; // 对应右上方方向超出
            if(C < 0 || C >= n) R = r + 1, C = c; // 对应左下方方向超出
        }
        DFS(matrix, res, R, C, m, n, dir, d);
    }
};

如果有任何疑问,欢迎提出。如果有更好的解法,也欢迎告知。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值