矩阵最长递增路径

144 阅读3分钟

描述

给定一个 n 行 m 列矩阵 matrix ,矩阵内所有数均为非负整数。 你需要在矩阵中找到一条最长路径,使这条路径上的元素是递增的。并输出这条最长路径的长度。

这个路径必须满足以下条件:

  1. 对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外。

  2. 你不能走重复的单元格。即每个格子最多只能走一次。

数据范围:1≤n,m≤10001≤n,m≤1000,0≤matrix[i][j]≤10000≤matrix[i][j]≤1000

进阶:空间复杂度 O(nm)O(nm) ,时间复杂度 O(nm)O(nm)

例如:当输入为[[1,2,3],[4,5,6],[7,8,9]]时,对应的输出为5,

其中的一条最长递增路径如下图所示:

示例1

输入:

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

返回值:

5

说明:

1->2->3->6->9即可。当然这种递增路径不是唯一的。       

示例2

输入:

[[1,2],[4,3]]

返回值:

4

说明:

 1->2->3->4   

备注:

矩阵的长和宽均不大于1000,矩阵内每个数不大于1000

记忆化搜索

  • 我们发现,如果我们在某一个过程中遍历到了(x,y)这个位置的时候,我们可以利用递归计算出这个位置开始可以走多少步。那么如果我们下次计算新的起始点的时候再走到了这个位置的时候,我们没有必要继续执行递归的操作了,我们可以直接利用之前递归得到的结果拿来用就行了。但是这样的方法我们需要额外开空间存储所有的位置的状态,这就是典型的空间换时间的做法,如果到了某一个位置的时候已经计算过,我们直接用,这样就减少了遍历的必要。

  • 代码如下

    • 每个位置只需要遍历一次,所以总的时间复杂度为O(nm)O(nm)O(nm)
    • 需要存储每个位置为起始点的时候的状态,同时递归的层数为nm,空间复杂为O(nm)O(nm)O(nm)
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 递增路径的最大长度
     * @param matrix int整型vector<vector<>> 描述矩阵的每个数
     * @return int整型
     */
    int dfs(vector<vector<int> > &mat,vector<vector<int> > &dp,int x,int y,int pre){
        if(mat[x][y]<=pre){
            return 0;
        }
        int n=mat.size();
        int m=mat[0].size();
        // 进行记忆化搜索
        if(dp[x][y]!=-1){
            return dp[x][y];
        }
        int mx=0;
        // 分别向四个方向进行转移
        if(x+1<n){
            mx=max(mx,dfs(mat,dp,x+1,y,mat[x][y]));
        }
        if(x-1>=0){
            mx=max(mx,dfs(mat,dp,x-1,y,mat[x][y]));
        }
        if(y-1>=0){
            mx=max(mx,dfs(mat,dp,x,y-1,mat[x][y]));
        }
        if(y+1<m){
            mx=max(mx,dfs(mat,dp,x,y+1,mat[x][y]));
        }
        
        // 更新这个位置的状态
        dp[x][y]=mx+1;
        
        return mx+1;
    }
    int solve(vector<vector<int> >& matrix) {
        // write code here
        
        int n=matrix.size();
        // 特判为空的情况
        if(n==0){
            return 0;
        }
        int m=matrix[0].size();
        // 初始化操作
        vector<vector<int> > dp(n,vector<int> (m,-1));
        int ans=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                ans=max(ans,dfs(matrix,dp,i,j,-1));
            }
        }
        
        return ans;
    }
};