此题为动态规划问题,首先想到的是递归,写一个dfs(i,j),枚举出向右边的三个方向走,对应的格子没有出界且格子的值大于grid[i][j],就有
dfs(i,j) = max(dfs(i-1,j+1) +1 , dfs(i,j+1) + 1, dfs(i+1,j+1)+1)
但此方法的时间复杂度为O(m*n),会超时,代码如下:
// class Solution {
// public:
// int maxMoves(vector<vector<int>>& grid) {
// int res = 0 ;
// for(int i = 0; i < grid.size(); i++)
// {
// res = max(res,dfs(i,0,grid));
// }
// return res;
// }
// int dfs(int i, int j, vector<vector<int>> grid)
// {
// if(j == grid[0].size()-1 ) return 0;
// int res = 0;
// int w = 0, q = 0;
// for(int p = i-1; p < i+2; p++)
// {
// if(0 <= p && p <grid.size())
// {
// w = grid[p][j+1];
// q = grid[i][j];
// if(w > q)
// res = max(res,dfs(p,j+1,grid)+1);
// }
// //if(int(grid[p][j+1]) > int())
// }
// return res;
// }
// };
需要三步完成:
1.将dfs改为f数组
2.递归改为循环,由于递归是从左向右移动,所以递推是从右到左移动。
3.递归的边界改为f数组的初始值。
代码如下所示:
class Solution {
public:
int maxMoves(vector<vector<int>>& grid) {
int m = grid.size(), n = grid[0].size();
int res = 0 ;
int w = 0, q = 0;
int f[m][n];
memset(f,0,sizeof(f));
for(int j = n -2; j >= 0; j--)
for(int i = 0; i < m; i++)
for(int p = max(i-1, 0); p < min(i+2, m); p++)
{
if(grid[p][j+1] > grid[i][j])
f[i][j] = max(f[i][j],f[p][j + 1] + 1);
}
int ans = 0;
for(int i=0; i<m; i++)
ans = max(ans,f[i][0]);
return ans;
}
};