题解 | #矩阵最长递增路径#(dfs+记忆数组)
矩阵最长递增路径
http://www.nowcoder.com/practice/7a71a88cdf294ce6bdf54c899be967a2
常规的dfs+记忆数组模板做法
class Solution {
public:
vector<int> order = {-1,0,1,0,-1}; // 递归方向
int rows;
int cols;
int solve(vector<vector<int> >& matrix) {
int res=0;
// write code here
rows = matrix.size();
cols = matrix[0].size();
if(rows==0 || cols==0) return 0;
vector<vector<bool> > visited(rows, vector<bool>(cols, false)); // 声明访问数组
vector<vector<int> > dp(rows, vector<int>(cols, 0)); // 记忆数组 剪枝
for(int i=0; i<rows; i++){
for(int j=0; j<cols; j++){
int temp = dfs(matrix, i, j, visited, dp); // 每个点初始化进行递归
res = max(res, temp);
}
}
return res;
}
int dfs(vector<vector<int> >& matrix, int i, int j, vector<vector<bool>>& visited, vector<vector<int>>& dp){
if(dp[i][j] != 0) return dp[i][j]; // 已经得到结果,直接返回
visited[i][j] = true; // 标记访问
int ans = 0;
for(int k=0; k<4; k++){
// 下一个点坐标
int x = i + order[k];
int y = j + order[k+1];
if(x<0 || x>=rows) continue; // 越界跳出
if(y<0 || y>=cols) continue;
if( matrix[i][j] < matrix[x][y]) { // 下一个点没有被访问,且下一个点大于前一个点 进入递归
int val = dfs(matrix, x, y, visited, dp); //返回该方向路径值
ans = max(val, ans); // 获得四个方向的最大值
}
}
visited[i][j] = false; // 回溯
ans += 1; // 当前路径的结果
dp[i][j] = ans; // 保存结果
return ans;
}
};
该题目中可以去掉访问数组,因为判断条件要求下一个节点值必须大于当前节点,其实就默认不会遍历已经访问过的数组,简化后得到:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 递增路径的最大长度
* @param matrix int整型vector<vector<>> 描述矩阵的每个数
* @return int整型
*/
int cols, rows;
int direct[5] = {1, 0, -1, 0, 1};
int solve(vector<vector<int> >& matrix) {
// write code here
rows=matrix.size();
cols = matrix[0].size();
vector<vector<int> > dp(rows,vector<int> (cols, -1));
int ans=0;
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
ans=max(ans,dfs(matrix,dp,i,j,-1));
}
}
return ans;
}
int dfs(vector<vector<int> > &mat,vector<vector<int> > &dp, int i, int j, int pre){
if(i<0||j<0||i>=rows||j>=cols||pre >= mat[i][j]) return 0;
if(dp[i][j]!=-1){
return dp[i][j];
}
int tmp = 0;
for(int k=0; k<4;k++){
int x = i + direct[k];
int y = j + direct[k+1];
tmp = max(tmp, dfs(mat, dp, x, y, mat[i][j]));
}
dp[i][j]= tmp+1;
return dp[i][j];
}
};
note:不能习惯性k用成i,全局变量下已经有i了,否则会一直报错。。。全局变量还是不要用习惯ijk,还是用x,y等符号比较好。
for(int k=0; k<4;k++){
int x = i + direct[k];
int y = j + direct[k+1];
tmp = max(tmp, dfs(mat, dp, x, y, mat[i][j]));
}