Problem
You are given a 2-d matrix
where each cell represents number of coins in that cell. Assuming we start at matrix[0][0]
, and can only move right or down, find the maximum number of coins you can collect by the bottom right corner.
Examples
Example 1
$$ \begin{array}{|c|c|c|c|} \hline \colorbox{green}0 & 3 & 1 & 1 \\ \hline \colorbox{green}2 & 0 & 0 & 4 \\ \hline \colorbox{green}1 & \colorbox{green}5 & \colorbox{green}3 & \colorbox{green}1 \\ \hline \end{array} $$
Input: matrix = [
[0, 3, 1, 1],
[2, 0, 0, 4],
[1, 5, 3, 1]
]
Output: 12
Explanation: The most we can collect is 0 + 2 + 1 + 5 + 3 + 1 = 12 coins.
Solution
Method 1 - DP
To achieve the maximum number of coins, use dynamic programming to keep track of the maximum coins collected up to each cell. For each cell, the maximum coins collected will be the maximum of coins collected from the cell above it or the cell to the left of it plus the coins in the current cell.
Approach
- Create a DP table (
dp
) of the same dimensions as the input matrix. - Initialize
dp[0][0]
tomatrix[0][0]
since that’s the starting point. - Fill in the first row and first column of the DP table since movements are restricted to right or down.
- For each remaining cell
(i, j)
, compute the maximum coins collected by considering either coming from the top (dp[i-1][j]
) or from the left (dp[i][j-1]
), and add the coins in the current cell. - The value at
dp[m-1][n-1]
(bottom-right corner) will give the maximum number of coins collected.
Code
Java
public class Solution {
public int maxCoins(int[][] matrix) {
int m = matrix.length;
int n = matrix[0].length;
int[][] dp = new int[m][n];
dp[0][0] = matrix[0][0];
// Initialize first row
for (int j = 1; j < n; j++) {
dp[0][j] = dp[0][j - 1] + matrix[0][j];
}
// Initialize first column
for (int i = 1; i < m; i++) {
dp[i][0] = dp[i - 1][0] + matrix[i][0];
}
// Fill the rest of the dp table
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = matrix[i][j] + Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
return dp[m - 1][n - 1];
}
public static void main(String[] args) {
Solution solution = new Solution();
int[][] matrix = {
{0, 3, 1, 1},
{2, 0, 0, 4},
{1, 5, 3, 1}
};
System.out.println(solution.maxCoins(matrix)); // Output: 12
}
}
Python
class Solution:
def maxCoins(self, matrix: List[List[int]]) -> int:
m, n = len(matrix), len(matrix[0])
dp = [[0]*n for _ in range(m)]
dp[0][0] = matrix[0][0]
# Initialize first row
for j in range(1, n):
dp[0][j] = dp[0][j - 1] + matrix[0][j]
# Initialize first column
for i in range(1, m):
dp[i][0] = dp[i - 1][0] + matrix[i][0]
# Fill the rest of the dp table
for i in range(1, m):
for j in range(1, n):
dp[i][j] = matrix[i][j] + max(dp[i - 1][j], dp[i][j - 1])
return dp[m - 1][n - 1]
# For testing the solution
if __name__ == "__main__":
solution = Solution()
matrix = [
[0, 3, 1, 1],
[2, 0, 0, 4],
[1, 5, 3, 1]
]
print(solution.maxCoins(matrix)) # Output: 12
Complexity
- ⏰ Time complexity:
O(m * n)
wherem
is the number of rows andn
is the number of columns. - 🧺 Space complexity:
O(m * n)
for the DP table.