Maximum sum path in a matrix from top-left to bottom-right
Given a matrix mat[][] of dimensions N * M, the task is to find the path from the top-left cell (0, 0) to the bottom-right cell (N – 1, M – 1) of the given matrix such that sum of the elements in the path is maximum. The only moves allowed from any cell (i, j) of the matrix are (i + 1, j) or (i, j + 1).
Examples:
Input: mat[][] = {{3, 7}, {9, 8}}
Output: 20
Explanation:
Path with maximum sum is 3 => 9 => 8 as 20.
Input: mat[][] = {{1, 2}, {3, 5}}
Output: 9
Explanation:
Path with maximum sum is 1 => 3 => 5 as 9
Approach 1 (Bottom-Up): The idea is to use Dynamic Programming to solve this problem. The key observation is that the cell grid[i][j] can only be reached from grid[i – 1][j] or grid[i][j – 1]. Therefore, the recurrence relation for this problem is given by the equation:
sum(i, j) = max(sum(i – 1, j), sum(i, j – 1)) + grid[i][j]
- Initialize an auxiliary matrix sum[][] of dimensions N * M.
- Iterate over the matrix elements and update each cell of the auxiliary matrix sum[][] using the above recurrence relation formed.
- After completing the above steps, the value sum[N][M] will contain the maximum sum possible for a path from the top-left corner to the bottom-right corner of the given matrix. Print that sum.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int MaximumPath(vector<vector< int > >& grid)
{
int N = grid.size();
int M = grid[0].size();
vector<vector< int > > sum;
sum.resize(N + 1,
vector< int >(M + 1));
for ( int i = 1; i <= N; i++) {
for ( int j = 1; j <= M; j++) {
sum[i][j] = max(sum[i - 1][j],
sum[i][j - 1])
+ grid[i - 1][j - 1];
}
}
return sum[N][M];
}
int main()
{
vector<vector< int > > grid
= { { 1, 2 }, { 3, 5 } };
cout << MaximumPath(grid);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int MaximumPath( int [][]grid)
{
int N = grid.length;
int M = grid[ 0 ].length;
int [][]sum = new int [N + 1 ][M + 1 ];
for ( int i = 1 ; i <= N; i++)
{
for ( int j = 1 ; j <= M; j++)
{
sum[i][j] = Math.max(sum[i - 1 ][j],
sum[i][j - 1 ]) +
grid[i - 1 ][j - 1 ];
}
}
return sum[N][M];
}
public static void main(String[] args)
{
int [][]grid = {{ 1 , 2 }, { 3 , 5 }};
System.out.print(MaximumPath(grid));
}
}
|
Python3
def MaximumPath(grid):
N = len (grid)
M = len (grid[ 0 ])
sum = [[ 0 for i in range (M + 1 )]
for i in range (N + 1 )]
for i in range ( 1 , N + 1 ):
for j in range ( 1 , M + 1 ):
sum [i][j] = ( max ( sum [i - 1 ][j],
sum [i][j - 1 ]) +
grid[i - 1 ][j - 1 ])
return sum [N][M]
if __name__ = = '__main__' :
grid = [ [ 1 , 2 ], [ 3 , 5 ] ]
print (MaximumPath(grid))
|
C#
using System;
class GFG{
static int MaximumPath( int [,]grid)
{
int N = grid.GetLength(0);
int M = grid.GetLength(1);
int [,]sum = new int [N + 1, M + 1];
for ( int i = 1; i <= N; i++)
{
for ( int j = 1; j <= M; j++)
{
sum[i, j] = Math.Max(sum[i - 1, j],
sum[i, j - 1]) +
grid[i - 1, j - 1];
}
}
return sum[N, M];
}
public static void Main(String[] args)
{
int [,]grid = { { 1, 2 }, { 3, 5 } };
Console.Write(MaximumPath(grid));
}
}
|
Javascript
<script>
function MaximumPath(grid)
{
let N = grid.length;
let M = grid[0].length;
let sum = new Array(N + 1);
for ( var i = 0; i < sum.length; i++) {
sum[i] = new Array(2);
}
for ( var i = 0; i < sum.length; i++) {
for ( var j = 0; j < sum.length; j++) {
sum[i][j] = 0;
}
}
for (let i = 1; i <= N; i++)
{
for (let j = 1; j <= M; j++)
{
sum[i][j] = Math.max(sum[i - 1][j],
sum[i][j - 1]) +
grid[i - 1][j - 1];
}
}
return sum[N][M];
}
let grid = [[1, 2], [3, 5]];
document.write(MaximumPath(grid));
</script>
|
Time Complexity: O(N * M)
Auxiliary Space: O(N * M)
Approach 2 (Top-Down): We will solve the problem recursively in a top-down manner. We formulate the recurrence based on the two ways of reaching the cell grid[i][j] as follows:
- If we move one step towards the right, from the cell grid[i][j-1] or,
- If we move one step downwards, from the cell grid[i-1][j].
dp[i][j] = max(dp[i][j-1], dp[i-1][j]) + grid[i][j]
Thus, we need to select the step (between the above two) which gives us the maximum value. Also, we need to add the value present in the cell we step into, i.e. grid[i][j]. As this problem has got the property of overlapping subproblems, we can store the result (memoize) of the subproblems in a 2D matrix (let’s call it dp), in order to avoid repeated computations of the same subproblems. Initially, we set all the cells in the dp table with the value -1, and every time we find an answer to a subproblem we overwrite its result in the respective cell in the dp table. Thus, before computing any subproblem we once check that – if that particular subproblem has been previously solved or not, if it has been solved (i.e. its corresponding cell the dp matrix is not -1) we simple return that value, else we solve it and store the result in the dp table.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector<vector< int > > dp;
int MaximumPathUtil( int i, int j, vector<vector< int > >& grid)
{
if (i == 0 || j == 0)
return 0;
if (dp[i][j] != -1)
return dp[i][j];
return dp[i][j] = max(MaximumPathUtil(i, j-1, grid), MaximumPathUtil(i - 1, j, grid)) +
grid[i-1][j-1];
}
int MaximumPath(vector<vector< int > >& grid)
{
int n = grid.size();
int m = grid[0].size();
dp.resize(n+1, vector< int > (m+1, -1));
return MaximumPathUtil(n, m, grid);
}
int main()
{
vector<vector< int > > grid = {{3, 7, 9, 2, 7},
{9, 8, 3, 5, 5},
{1, 7, 9, 8, 6},
{3, 8, 6, 4, 9},
{6, 3, 9, 7, 8}};
cout << MaximumPath(grid);
return 0;
}
|
Java
import java.io.*;
class GFG {
static int dp [][];
static int MaximumPathUtil( int i, int j, int [][] grid)
{
if (i == 0 || j == 0 )
return 0 ;
if (dp[i][j] != - 1 )
return dp[i][j];
return dp[i][j] = Math.max(MaximumPathUtil(i, j- 1 , grid), MaximumPathUtil(i - 1 , j, grid)) +
grid[i- 1 ][j- 1 ];
}
static int MaximumPath( int [][] grid)
{
int n = grid.length;
int m = grid[ 0 ].length;
dp = new int [n+ 1 ][m+ 1 ];
for ( int i= 0 ;i<n+ 1 ;i++){
for ( int j= 0 ;j<m+ 1 ;j++){
dp[i][j] = - 1 ;
}
}
return MaximumPathUtil(n, m, grid);
}
public static void main(String args[])
{
int [][] grid = {{ 3 , 7 , 9 , 2 , 7 },
{ 9 , 8 , 3 , 5 , 5 },
{ 1 , 7 , 9 , 8 , 6 },
{ 3 , 8 , 6 , 4 , 9 },
{ 6 , 3 , 9 , 7 , 8 }};
System.out.println(MaximumPath(grid));
}
}
|
Python3
dp = []
def MaximumPathUtil(i, j, grid):
global dp
if (i = = 0 or j = = 0 ):
return 0
if (dp[i][j] ! = - 1 ):
return dp[i][j]
dp[i][j] = max (MaximumPathUtil(i, j - 1 , grid), MaximumPathUtil(i - 1 , j, grid)) + grid[i - 1 ][j - 1 ]
return dp[i][j]
def MaximumPath(grid):
global dp
n = len (grid)
m = len (grid[ 0 ])
dp = [[ - 1 for i in range (m + 1 )] for j in range (n + 1 )]
return MaximumPathUtil(n, m, grid)
grid = [[ 3 , 7 , 9 , 2 , 7 ],
[ 9 , 8 , 3 , 5 , 5 ],
[ 1 , 7 , 9 , 8 , 6 ],
[ 3 , 8 , 6 , 4 , 9 ],
[ 6 , 3 , 9 , 7 , 8 ]]
print (MaximumPath(grid))
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
class GFG
{
static int [][] dp;
static int MaximumPathUtil( int i, int j, int [][] grid)
{
if (i == 0 || j == 0){
return 0;
}
if (dp[i][j] != -1)
return dp[i][j];
return dp[i][j] = Math.Max(MaximumPathUtil(i, j-1, grid), MaximumPathUtil(i - 1, j, grid)) + grid[i-1][j-1];
}
static int MaximumPath( int [][] grid)
{
int n = grid.Length;
int m = grid[0].Length;
dp = new int [n+1][];
for ( int i = 0 ; i <= n ; i++){
dp[i] = new int [m + 1];
}
for ( int i = 0 ; i < n + 1 ; i++){
for ( int j = 0 ; j < m + 1 ; j++){
dp[i][j] = -1;
}
}
return MaximumPathUtil(n, m, grid);
}
public static void Main( string [] args){
int [][] grid = {
new int []{3, 7, 9, 2, 7},
new int []{9, 8, 3, 5, 5},
new int []{1, 7, 9, 8, 6},
new int []{3, 8, 6, 4, 9},
new int []{6, 3, 9, 7, 8}
};
Console.WriteLine(MaximumPath(grid));
}
}
|
Javascript
<script>
let dp = [];
function MaximumPathUtil(i, j, grid)
{
if (i == 0 || j == 0)
return 0;
if (dp[i][j] != -1)
return dp[i][j];
return dp[i][j] = Math.max(MaximumPathUtil(i, j-1, grid),
MaximumPathUtil(i - 1, j, grid)) +
grid[i-1][j-1];
}
function MaximumPath(grid)
{
let n = grid.length;
let m = grid[0].length;
dp = new Array(n+1);
for (let i = 0; i <= n; i++){
dp[i] = new Array(m + 1).fill(-1);
}
return MaximumPathUtil(n, m, grid);
}
let grid = [[3, 7, 9, 2, 7],
[9, 8, 3, 5, 5],
[1, 7, 9, 8, 6],
[3, 8, 6, 4, 9],
[6, 3, 9, 7, 8]];
document.write(MaximumPath(grid), "</br>" );
</script>
|
Output:
67
Time Complexity: O(n*m)
Space Complexity: O(n*m)
Last Updated :
20 Jun, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...