You are given a 0-indexedm x n matrix grid consisting of positive integers.
You can start at any cell in the first column of the matrix, and traverse the grid in the following way:
From a cell (row, col), you can move to any of the cells: (row - 1, col + 1), (row, col + 1) and (row + 1, col + 1) such that the value of the cell you move to, should be strictly bigger than the value of the current cell.
Return the maximum number of moves that you can perform.
Input: grid =[[2,4,3,5],[5,4,9,3],[3,4,2,11],[10,9,13,15]]Output: 3Explanation: We can start at the cell(0,0) and make the following moves:-(0,0)->(0,1).-(0,1)->(1,2).-(1,2)->(2,3).It can be shown that it is the maximum number of moves that can be made.
In this approach, we simply recurse through each possible move without storing intermediate results. This means that the same subproblem might be solved multiple times, resulting in an exponential time complexity.
Here is the approach:
For each cell (row, col), recursively check the possible moves (row-1, col+1), (row, col+1), and (row+1, col+1).
Directly compute the number of moves from each cell.
classSolution {
privateintdfs(int[][] grid, int row, int col) {
int m = grid.length, n = grid[0].length;
if (col == n - 1) { // If it's the last column, no further moves possible.return 0;
}
int max_moves = 0;
if (row > 0 && grid[row - 1][col + 1]> grid[row][col]) {
max_moves = Math.max(max_moves, 1 + dfs(grid, row - 1, col + 1));
}
if (grid[row][col + 1]> grid[row][col]) {
max_moves = Math.max(max_moves, 1 + dfs(grid, row, col + 1));
}
if (row < m - 1 && grid[row + 1][col + 1]> grid[row][col]) {
max_moves = Math.max(max_moves, 1 + dfs(grid, row + 1, col + 1));
}
return max_moves;
}
publicintmaxMoves(int[][] grid) {
int m = grid.length;
int ans = 0;
for (int row = 0; row < m; row++) {
ans = Math.max(ans, dfs(grid, row, 0));
}
return ans;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
classSolution:
defmaxMoves(self, grid: List[List[int]]) -> int:
m, n = len(grid), len(grid[0])
defdfs(row: int, col: int) -> int:
if col == n -1: # If it's the last column, no further moves possible.return0 max_moves =0 directions = [(1, 1), (0, 1), (-1, 1)]
for dr, dc in directions:
new_row, new_col = row + dr, col + dc
if0<= new_row < m and new_col < n and grid[new_row][new_col] > grid[row][col]:
max_moves = max(max_moves, 1+ dfs(new_row, new_col))
return max_moves
return max(dfs(row, 0) for row in range(m))
classSolution {
privateintdfs(int[][] grid, int row, int col, int[][] memo) {
if (col == grid[0].length- 1) return 0;
if (memo[row][col]!=-1) return memo[row][col];
int max_moves = 0;
if (row > 0 && grid[row - 1][col + 1]> grid[row][col]) {
max_moves = Math.max(max_moves, 1 + dfs(grid, row - 1, col + 1, memo));
}
if (grid[row][col + 1]> grid[row][col]) {
max_moves = Math.max(max_moves, 1 + dfs(grid, row, col + 1, memo));
}
if (row < grid.length- 1 && grid[row + 1][col + 1]> grid[row][col]) {
max_moves = Math.max(max_moves, 1 + dfs(grid, row + 1, col + 1, memo));
}
return memo[row][col]= max_moves;
}
publicintmaxMoves(int[][] grid) {
int m = grid.length, n = grid[0].length;
int[][] memo =newint[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
memo[i][j]=-1;
}
}
int ans = 0;
for (int row = 0; row < m; row++) {
ans = Math.max(ans, dfs(grid, row, 0, memo));
}
return ans;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution:
defmaxMoves(self, grid: List[List[int]]) -> int:
m, n = len(grid), len(grid[0])
memo = [[-1] * n for _ in range(m)]
defdfs(row: int, col: int) -> int:
if memo[row][col] !=-1:
return memo[row][col]
max_moves =0 directions = [(1, 1), (0, 1), (-1, 1)]
for dr, dc in directions:
new_row, new_col = row + dr, col + dc
if0<= new_row < m and new_col < n and grid[new_row][new_col] > grid[row][col]:
max_moves = max(max_moves, 1+ dfs(new_row, new_col))
memo[row][col] = max_moves
return max_moves
return max(dfs(row, 0) for row in range(m))
The bottom-up DP approach involves initializing a DP array and iteratively calculating the maximum moves for each cell starting from the last column to the first.
Use an auxiliary DP array to store the maximum number of moves possible ending at each cell.
Iterate through the matrix from the last column to the first column.
Here is the approach:
Initialization: Start by initializing a DP array dp with same dimension as grid and all elements set to zero.
Transition: For each cell (row, col), calculate the dp[row][col] based on the possible moves:
(row-1, col+1), (row, col+1), and (row+1, col+1).
Update dp[row][col] if moving to a neighbouring cell yields a higher number of moves.
Result: The answer will be the maximum value in the first column of the DP array, which signifies the starting points with the highest number of moves.
classSolution {
publicintmaxMoves(int[][] grid) {
int m = grid.length, n = grid[0].length;
int[][] dp =newint[m][n];
int ans = 0;
for (int col = n - 2; col >= 0; col--) {
for (int row = 0; row < m; row++) {
if (col == 0) dp[row][col]= 0;
if (row > 0 && grid[row - 1][col + 1]> grid[row][col]) {
dp[row][col]= Math.max(dp[row][col], dp[row - 1][col + 1]+ 1);
}
if (grid[row][col + 1]> grid[row][col]) {
dp[row][col]= Math.max(dp[row][col], dp[row][col + 1]+ 1);
}
if (row < m - 1 && grid[row + 1][col + 1]> grid[row][col]) {
dp[row][col]= Math.max(dp[row][col], dp[row + 1][col + 1]+ 1);
}
if (col == 0) {
ans = Math.max(ans, dp[row][col]);
}
}
}
return ans;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution:
defmaxMoves(self, grid: List[List[int]]) -> int:
m, n = len(grid), len(grid[0])
dp = [[0] * n for _ in range(m)]
ans =0for col in range(n -2, -1, -1):
for row in range(m):
if row >0and grid[row -1][col +1] > grid[row][col]:
dp[row][col] = max(dp[row][col], dp[row -1][col +1] +1)
if grid[row][col +1] > grid[row][col]:
dp[row][col] = max(dp[row][col], dp[row][col +1] +1)
if row < m -1and grid[row +1][col +1] > grid[row][col]:
dp[row][col] = max(dp[row][col], dp[row +1][col +1] +1)
if col ==0:
ans = max(ans, dp[row][col])
return ans