给你一个下标从 0 开始、大小为 m x n 的矩阵 grid ,矩阵由若干 正 整数组成。
你可以从矩阵第一列中的 任一 单元格出发,按以下方式遍历 grid :
从单元格 (row, col) 可以移动到 (row - 1, col + 1)、(row, col + 1) 和 (row + 1, col + 1) 三个单元格中任一满足值 严格 大于当前单元格的单元格。
返回你在矩阵中能够 移动 的 最大 次数。
示例 1:
输入:grid = [[2,4,3,5],[5,4,9,3],[3,4,2,11],[10,9,13,15]]
输出:3
解释:可以从单元格 (0, 0) 开始并且按下面的路径移动:
- (0, 0) -> (0, 1).
- (0, 1) -> (1, 2).
- (1, 2) -> (2, 3).
可以证明这是能够移动的最大次数。
示例 2:
输入: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();
int max_moves = 0;
vector<vector<int>> memo(m, vector<int>(n, -1));
for(int i = 0; i < m; i++){
max_moves = max(max_moves,def(grid, i, 0, memo));
}
return max_moves;
}
private:
int def(vector<vector<int>>& grid, int row, int col, vector<vector<int>>& memo) {
int m = grid.size(), n = grid[0].size();
if(col == n - 1){
return 0;
}
if(memo[row][col] != -1){
return memo[row][col];
}
int move = 0;
//右上
if(row > 0 && grid[row][col] < grid[row-1][col+1]){
move = max(move, 1 + def(grid, row - 1, col + 1, memo));
}
//右下
if(row < m - 1 && grid[row][col] < grid[row+1][col+1]){
move = max(move, 1 + def(grid, row + 1, col + 1, memo));
}
//右
if(grid[row][col] < grid[row][col+1]){
move = max(move, 1 + def(grid, row, col + 1, memo));
}
memo[row][col] = move;
return move;
}
};
在主函数里面对第一列每个元素进行递归,在def函数中,设定一个move来判断当前格子开始能移动的最大次数,move在每次递归中会重新归0。
def函数中对三种情况,右上、右、右下进行判断,然后进行对应的递归。
当到最后一行到时候,则会返回0,如果三个if判断都不通过,则move = 0,最后的结果也是返回0。
并且使用了memo进行缓存,当计算对应位置的move的时候,如果之前计算过,就不需要进行计算,直接返回memo中的缓存。