1.DFS

#include <vector>
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 递增路径的最大长度
     * @param matrix int整型vector<vector<>> 描述矩阵的每个数
     * @return int整型
     */
    void dfs(vector<vector<int>>& matrix,int &count,vector<vector<int>>& visited,int i,int j,int n,int m,int &max)
    {
        visited[i][j] = 1;
        count++;
        if(max < count)
            max = count;
        if(i-1>=0 && visited[i-1][j] == 0 && matrix[i-1][j] > matrix[i][j])
            dfs(matrix, count, visited, i-1, j, n, m,max);
        if(i+1<n && visited[i+1][j] == 0 && matrix[i+1][j] > matrix[i][j])
            dfs(matrix, count, visited, i+1, j, n, m,max);
        if(j-1>=0 && visited[i][j-1] == 0 && matrix[i][j-1] > matrix[i][j])
            dfs(matrix, count, visited, i, j-1, n, m,max);
        if(j+1<m && visited[i][j+1] == 0 && matrix[i][j+1] > matrix[i][j])
            dfs(matrix, count, visited, i, j+1, n, m,max);
        visited[i][j] = 0;
        count--;
    }
    int solve(vector<vector<int> >& matrix) {
        // write code here
        int count = 0;
        int n = matrix.size();
        int m = matrix[0].size();
        int max = 0;
        vector<vector<int>> visited(n,vector<int>(m,0));
        for(int i = 0;i<n;++i)
        {
            for(int j = 0;j<m;++j)
            {
                dfs(matrix, count, visited, i, j, n, m, max);
            }
        }
        return max;
    }
};

2.BFS

思路:

我们可以将矩阵看成是一个有向图,一个元素到另一个元素递增,代表有向图的箭头。这样我们可以根据有向图的出度入度找到最长的路径,且这个路径在矩阵中就是递增的。

具体做法:

  • step 1:计算每个节点(单元格)所对应的出度(符合边界条件且递增),对于作为边界条件的单元格,它的值比所有的相邻单元格的值都要大,因此作为边界条件的单元格的出度都为0。利用一个二维矩阵记录每个单元格的出度
  • step 2:利用拓扑排序的思想,从所有出度为0的单元格开始进行广度优先搜索。
  • step 3:借助队列来广度优先搜索,队列中每次加入出度为0的点,即路径最远点,每次从A点到B点,便将A点出度减一。
  • step 4:每次搜索都会遍历当前层的所有单元格,更新其余单元格的出度,并将出度变为0的单元格加入下一层搜索。
  • step 5:当搜索结束时,搜索的总层数即为矩阵中的最长递增路径的长度,因为bfs的层数就是路径增长的层数。
#include <queue>
#include <vector>
class Solution {
public:
    int solve(vector<vector<int> >& matrix) {
        // write code here
        int n = matrix.size();
        int m = matrix[0].size();
        int dirs[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};//记录四个方向
        vector<vector<int>> outdegrees(n,vector<int>(m,0));//记录每个单元的出度
        for(int i = 0;i<n;i++)
        {
            for(int j = 0;j<m;j++)
            {
                for(int k = 0;k<4;k++)
                {
                    int nexti = i + dirs[k][0];
                    int nextj = j + dirs[k][1];
                    if(nexti >= 0 && nexti < n && nextj >= 0 && nextj < m && matrix[nexti][nextj] > matrix[i][j])
                    {
                        outdegrees[i][j]++;//符合条件,记录出度
                    }
                } 
            }
        }
        queue<pair<int,int>> q;
        for(int i = 0;i<n;i++)
        {
            for(int j = 0;j<m;j++)
            {
                //出度为0的数就是周围的数都比它的小的那些数
                if(outdegrees[i][j] == 0)
                    q.push({i,j});//找到出度为0的入队列
            }
        }
        int res = 0;
        //逆向思维:从路径最远点出发,找到路径的头,也就是出度为0的点,途中记录该路径的长度
        while(!q.empty())
        {
            res++;
            int size = q.size();
            for(int x = 0;x < size ; x++)
            {
                pair<int,int> temp = q.front();
                q.pop();
                int i = temp.first;
                int j = temp.second;
                //四个方向
                for(int k = 0;k<4;++k)
                {
                    int nexti = i + dirs[k][0];
                    int nextj = j + dirs[k][1];
                    //逆向搜索,所以下一步是小于
                    if(nexti >= 0 && nexti < n && nextj >= 0 && nextj < m && matrix[nexti][nextj] < matrix[i][j])
                    {
                        //符合条件,出度递减
                        outdegrees[nexti][nextj]--;
                        if(outdegrees[nexti][nextj] == 0)
                            q.push({nexti,nextj});
                    }
                }
            }
        }
        return res;

    }
};