给你一个下标从 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 解释:从第一列的任一单元格开始都无法移动。
题解:还是一样思路,对于移动到任意一个单元格,都存在三种走法,如果这三种走法不能走就直接返回。 (row, col)
-> (row - 1, col + 1)
、(row, col + 1)
和 (row + 1, col + 1)并且移动到下一个单元格要
严格 大于当前单元格的单元格。
方法一:暴力递归
class Solution {
public static int maxMoves(int[][] grid) {
int max = 0;
// int[][] tmp = { { -1, 1 }, { 0, 1 }, { 1, 1 } };
for (int i = 0; i < grid.length; i++) {
max = Math.max(max, process(grid, i, 0));
}
return max;
}
public static int process(int[][] grid, int row, int col) {
if (row < 0 || row >= grid.length || col >= grid[0].length)
return 0;
// (row - 1, col + 1)
int l1 = 0;
if (row - 1 >= 0 && col + 1 < grid[0].length && grid[row][col] < grid[row - 1][col + 1])
l1 = process(grid, row - 1, col+1) + 1;
// (row, col + 1)
int l2 = 0;
if (col + 1 < grid[0].length && grid[row][col] < grid[row][col + 1])
l2 = process(grid, row, col + 1) + 1;
// (row + 1, col + 1)
int l3 = 0;
if (row + 1 < grid.length && col + 1 < grid[0].length && grid[row][col] < grid[row + 1][col + 1])
l3 = process(grid, row + 1, col + 1) + 1;
return Math.max(l1, Math.max(l2, l3));
}
}
不过没几个用例了,可直接加一个记忆化搜索,应该就能通过测试用例。因为对于每一个单元格接下来走的最大步数是相同的,所以可以将递归的存储起来。
方法二:记忆化搜索
class Solution {
public static int maxMoves(int[][] grid) {
int max = 0;
int[][] dp =new int[grid.length+1][grid[0].length+1];
for (int i = 0; i < grid.length; i++) {
max = Math.max(max, process(grid, i, 0,dp));
}
return max;
}
public static int process(int[][] grid, int row, int col,int[][] dp) {
if(dp[row][col]!=0)
return dp[row][col];
if (row < 0 || row >= grid.length || col >= grid[0].length)
return 0;
// (row - 1, col + 1)
int l1 = 0;
if (row - 1 >= 0 && col + 1 < grid[0].length && grid[row][col] < grid[row - 1][col + 1])
l1 = process(grid, row - 1, col + 1,dp) + 1;
// (row, col + 1)
int l2 = 0;
if (col + 1 < grid[0].length && grid[row][col] < grid[row][col + 1])
l2 = process(grid, row, col + 1,dp) + 1;
// (row + 1, col + 1)
int l3 = 0;
if (row + 1 < grid.length && col + 1 < grid[0].length && grid[row][col] < grid[row + 1][col + 1])
l3 = process(grid, row + 1, col + 1,dp) + 1;
dp[row][col] = Math.max(l1, Math.max(l2, l3));
return dp[row][col];
}
}
这样子就通过了,其实应该还有进阶版本的,递推版本的动态规划。在此就不写了,能过就行。。。。