题目

给你一个下标从 0 开始、大小为 m x n 的矩阵 grid ,矩阵由若干 正 整数组成。
你可以从矩阵第一列中的 任一 单元格出发,按以下方式遍历 grid :
从单元格 (row, col) 可以移动到 (row - 1, col + 1)、(row, col + 1) 和 (row + 1, col + 1) 三个单元格中任一满足值 严格 大于当前单元格的单元格。
返回你在矩阵中能够 移动 的 最大 次数。

示例

输入:grid = [[2,4,3,5],[5,4,9,3],[3,4,2,11],[10,9,13,15]]
输出:3
解释:可以从单元格 (0, 0) 开始并且按下面的路径移动:

输入:grid = [[3,2,4],[2,1,9],[1,1,7]]
输出:0
解释:从第一列的任一单元格开始都无法移动。

代码加对代码的理解

通过存储可行行号和备选行号来达到广度遍历

class Solution {
public:
    int maxMoves(vector<vector<int>>& grid) {
        int m = grid.size(),n = grid[0].size();
        //用set保证不重复 q存放行号
        unordered_set<int> q,q2;
        //默认每一行全部可行 放入q
        for(int i = 0;i < m;i++) q.insert(i);
        for(int j = 1;j < n;j++) 
        {
            //每一次遍历列 把q2重置
            q2.clear();
            //遍历q容器中的行编号
            for(int i : q)
            {
                //遍历i行的上一行,当前行和下一行
                for(int i2 = i - 1;i2 <= i + 1;i2++)
                {
                    //判断行号是否合法 然后判断当前行的前一列是否小于可能的行号和下一列
                    if(0 <= i2 && i2 < m && grid[i][j - 1] < grid[i2][j])
                    {
                        //i2是可行的行号 加入到 q2
                        q2.insert(i2);
                    }
                }
            }
            //把q2和q交换
            swap(q,q2);
            //如果没有可行的行号给到q
            if(q.empty())
            {
                //那么返回 j - 1
                return j - 1;
            }
        }
        //如果全部操作完还可行 证明可以到底
        return n - 1;
    }
};