Maximum sum path in a Matrix
Given an n*m matrix, the task is to find the maximum sum of elements of cells starting from the cell (0, 0) to cell (n-1, m-1).
However, the allowed moves are right, downwards or diagonally right, i.e, from location (i, j) next move can be (i+1, j), or, (i, j+1), or (i+1, j+1). Find the maximum sum of elements satisfying the allowed moves.
Examples:
Input:
mat[][] = {{100, -350, -200},
{-100, -300, 700}}
Output: 500
Explanation:
Path followed is 100 -> -300 -> 700
Input:
mat[][] = {{500, 100, 230},
{1000, 300, 100},
{200, 1000, 200}}
Explanation:
Path followed is 500 -> 1000 -> 300 -> 1000 -> 200
Naive Approach: Recursion
Going through the Naive approach by traversing every possible path. But, this is costly. So, use Dynamic Programming here in order to reduce the time complexity.
C++
#include <bits/stdc++.h>
using namespace std;
#define N 100
int n, m;
int a[N][N];
int current_sum = 0;
int total_sum = 0;
void inputMatrix()
{
n = 3;
m = 3;
a[0][0] = 500;
a[0][1] = 100;
a[0][2] = 230;
a[1][0] = 1000;
a[1][1] = 300;
a[1][2] = 100;
a[2][0] = 200;
a[2][1] = 1000;
a[2][2] = 200;
}
int maximum_sum_path( int i, int j)
{
if (i == n - 1 && j == m - 1)
return a[i][j];
if (i < n - 1 & j < m - 1) {
int current_sum = max(maximum_sum_path(i, j + 1),
max(
maximum_sum_path(i + 1, j + 1),
maximum_sum_path(i + 1, j)));
total_sum = a[i][j] + current_sum;
}
else if (i == n - 1)
total_sum = a[i][j]
+ maximum_sum_path(i, j + 1);
else
total_sum = a[i][j]
+ maximum_sum_path(i + 1, j);
return total_sum;
}
int main()
{
inputMatrix();
int maximum_sum = maximum_sum_path(0, 0);
cout << maximum_sum;
return 0;
}
|
Java
import java.io.*;
class GFG {
public static int maxPathSum( int matrix[][], int i, int j)
{
if (i< 0 || j< 0 ) {
return -100_000_000;
}
if (i== 0 && j== 0 ) {
return matrix[i][j];
}
int up = matrix[i][j] + maxPathSum(matrix, i - 1 , j);
int right = matrix[i][j] + maxPathSum(matrix, i, j - 1 );
int up_left_diagonal = matrix[i][j] + maxPathSum(matrix, i - 1 , j - 1 );
return Math.max(up , Math.max( right, up_left_diagonal));
}
public static void main(String[] args)
{
int matrix [][] ={{ 100 , - 350 , - 200 }, {- 100 , - 300 , 700 }};
System.out.print(maxPathSum(matrix, 1 , 2 ));
}
}
|
Python3
n = 0
m = 0
rows, cols = ( 100 , 100 )
a = [[ 0 for i in range (cols)] for j in range (rows)]
current_sum = 0
total_sum = 0
def inputMatrix():
global n, m, a
n = 3
m = 3
a[ 0 ][ 0 ] = 500
a[ 0 ][ 1 ] = 100
a[ 0 ][ 2 ] = 230
a[ 1 ][ 0 ] = 1000
a[ 1 ][ 1 ] = 300
a[ 1 ][ 2 ] = 100
a[ 2 ][ 0 ] = 200
a[ 2 ][ 1 ] = 1000
a[ 2 ][ 2 ] = 200
def maximum_sum_path(i, j):
global n, m, a, total_sum, current_sum
if i = = n - 1 and j = = m - 1 :
return a[i][j]
if (i < (n - 1 )) & (j < (m - 1 )):
current_sum = max (maximum_sum_path(
i, j + 1 ), max (maximum_sum_path(i + 1 , j + 1 ),
maximum_sum_path(i + 1 , j)))
total_sum = a[i][j] + current_sum
elif i = = n - 1 :
total_sum = a[i][j] + maximum_sum_path(i, j + 1 )
else :
total_sum = a[i][j] + maximum_sum_path(i + 1 , j)
return total_sum
if __name__ = = "__main__" :
inputMatrix()
maximum_sum = maximum_sum_path( 0 , 0 )
print (maximum_sum)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static readonly int N= 100;
static int n, m;
static int [,]a = new int [N, N];
static int current_sum = 0;
static int total_sum = 0;
static void inputMatrix()
{
n = 3;
m = 3;
a[0,0] = 500;
a[0,1] = 100;
a[0,2] = 230;
a[1,0] = 1000;
a[1,1] = 300;
a[1,2] = 100;
a[2,0] = 200;
a[2,1] = 1000;
a[2,2] = 200;
}
static int maximum_sum_path( int i, int j)
{
if (i == n - 1 && j == m - 1)
return a[i,j];
if (i < n - 1 & j < m - 1) {
int current_sum = Math.Max(maximum_sum_path(i, j + 1), Math.Max(maximum_sum_path(i + 1, j + 1), maximum_sum_path(i + 1, j)));
total_sum = a[i,j] + current_sum;
}
else if (i == n - 1)
total_sum = a[i,j] + maximum_sum_path(i, j + 1);
else
total_sum = a[i,j] + maximum_sum_path(i + 1, j);
return total_sum;
}
static void Main( string [] args)
{
inputMatrix();
int maximum_sum = maximum_sum_path(0, 0);
Console.Write(maximum_sum);
}
}
|
Javascript
<script>
const N = 100
let n, m;
let a = new Array(N);
for (let i=0;i<N;i++){
a[i] = new Array(N);
}
let current_sum = 0;
let total_sum = 0;
function inputMatrix()
{
n = 3;
m = 3;
a[0][0] = 500;
a[0][1] = 100;
a[0][2] = 230;
a[1][0] = 1000;
a[1][1] = 300;
a[1][2] = 100;
a[2][0] = 200;
a[2][1] = 1000;
a[2][2] = 200;
}
function maximum_sum_path(i, j)
{
if (i == n - 1 && j == m - 1)
return a[i][j];
if (i < n - 1 & j < m - 1) {
let current_sum = Math.max(maximum_sum_path(i, j + 1),
Math.max(
maximum_sum_path(i + 1, j + 1),
maximum_sum_path(i + 1, j)));
total_sum = a[i][j] + current_sum;
}
else if (i == n - 1)
total_sum = a[i][j]
+ maximum_sum_path(i, j + 1);
else
total_sum = a[i][j]
+ maximum_sum_path(i + 1, j);
return total_sum;
}
inputMatrix();
let maximum_sum = maximum_sum_path(0, 0);
document.write(maximum_sum, "</br>" );
</script>
|
Time Complexity: O(2N*M)
Auxiliary Space: O(N*M)
2. Efficient Approach(Memoization) : Dynamic programming is used to solve the above problem in a recursive way.
- Allot a position at the beginning of the matrix at (0, 0).
- Check each next allowed position from the current position and select the path with maximum sum.
- Take care of the boundaries of the matrix, i.e, if the position reaches the last row or last column then the only possible choice will be right or downwards respectively.
- Use a map to store track of all the visiting positions and before visiting any (i, j), check whether or not the position is visited before.
- Update the maximum of all possible paths returned by each recursive calls made.
- Go till the position reaches the destination cell, i.e, (n-1.m-1).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define N 100
int n, m;
int a[N][N];
vector<vector< int > > dp(N, vector< int >(N)),
visited(N, vector< int >(N));
int current_sum = 0;
int total_sum = 0;
void inputMatrix()
{
n = 3;
m = 3;
a[0][0] = 500;
a[0][1] = 100;
a[0][2] = 230;
a[1][0] = 1000;
a[1][1] = 300;
a[1][2] = 100;
a[2][0] = 200;
a[2][1] = 1000;
a[2][2] = 200;
}
int maximum_sum_path( int i, int j)
{
if (i == n - 1 && j == m - 1)
return a[i][j];
if (visited[i][j])
return dp[i][j];
visited[i][j] = 1;
int & total_sum = dp[i][j];
if (i < n - 1 & j < m - 1) {
int current_sum = max(maximum_sum_path(i, j + 1),
max(
maximum_sum_path(i + 1, j + 1),
maximum_sum_path(i + 1, j)));
total_sum = a[i][j] + current_sum;
}
else if (i == n - 1)
total_sum = a[i][j]
+ maximum_sum_path(i, j + 1);
else
total_sum = a[i][j]
+ maximum_sum_path(i + 1, j);
return dp[i][j] = total_sum;
}
int main()
{
inputMatrix();
int maximum_sum = maximum_sum_path(0, 0);
cout << maximum_sum;
return 0;
}
|
Java
class GFG{
static final int N = 100 ;
static int n, m;
static int a[][] = new int [N][N];
static int dp[][] = new int [N][N];
static int visited[][] = new int [N][N];
static int current_sum = 0 ;
static int total_sum = 0 ;
static void inputMatrix()
{
n = 3 ;
m = 3 ;
a[ 0 ][ 0 ] = 500 ;
a[ 0 ][ 1 ] = 100 ;
a[ 0 ][ 2 ] = 230 ;
a[ 1 ][ 0 ] = 1000 ;
a[ 1 ][ 1 ] = 300 ;
a[ 1 ][ 2 ] = 100 ;
a[ 2 ][ 0 ] = 200 ;
a[ 2 ][ 1 ] = 1000 ;
a[ 2 ][ 2 ] = 200 ;
}
static int maximum_sum_path( int i, int j)
{
if (i == n - 1 && j == m - 1 )
return a[i][j];
if (visited[i][j] != 0 )
return dp[i][j];
visited[i][j] = 1 ;
int total_sum = 0 ;
if (i < n - 1 & j < m - 1 )
{
int current_sum = Math.max(
maximum_sum_path(i, j + 1 ),
Math.max(
maximum_sum_path(i + 1 , j + 1 ),
maximum_sum_path(i + 1 , j)));
total_sum = a[i][j] + current_sum;
}
else if (i == n - 1 )
total_sum = a[i][j] +
maximum_sum_path(i, j + 1 );
else
total_sum = a[i][j] +
maximum_sum_path(i + 1 , j);
dp[i][j] = total_sum;
return total_sum;
}
public static void main(String[] args)
{
inputMatrix();
int maximum_sum = maximum_sum_path( 0 , 0 );
System.out.println(maximum_sum);
}
}
|
Python3
N = 100
n, m = - 1 , - 1
a = [[ - 1 ] * N for _ in range (N)]
dp,visited = [[ - 1 ] * N for _ in range (N)],[[ False ] * N for _ in range (N)]
current_sum = 0
total_sum = 0
def inputMatrix():
global n, m
n = 3
m = 3
a[ 0 ][ 0 ] = 500
a[ 0 ][ 1 ] = 100
a[ 0 ][ 2 ] = 230
a[ 1 ][ 0 ] = 1000
a[ 1 ][ 1 ] = 300
a[ 1 ][ 2 ] = 100
a[ 2 ][ 0 ] = 200
a[ 2 ][ 1 ] = 1000
a[ 2 ][ 2 ] = 200
def maximum_sum_path(i, j):
global total_sum
if (i = = n - 1 and j = = m - 1 ):
return a[i][j]
if (visited[i][j]):
return dp[i][j]
visited[i][j] = True
total_sum = dp[i][j]
if (i < n - 1 and j < m - 1 ) :
current_sum = max (maximum_sum_path(i, j + 1 ),
max (
maximum_sum_path(i + 1 , j + 1 ),
maximum_sum_path(i + 1 , j)))
total_sum = a[i][j] + current_sum
elif (i = = n - 1 ):
total_sum = a[i][j] + maximum_sum_path(i, j + 1 )
else :
total_sum = a[i][j] + maximum_sum_path(i + 1 , j)
dp[i][j] = total_sum
return total_sum
if __name__ = = '__main__' :
inputMatrix()
maximum_sum = maximum_sum_path( 0 , 0 )
print (maximum_sum)
|
C#
using System;
class GFG{
static readonly int N = 100;
static int n, m;
static int [,]a = new int [N, N];
static int [,]dp = new int [N, N];
static int [,]visited = new int [N, N];
static int current_sum = 0;
static int total_sum = 0;
static void inputMatrix()
{
n = 3;
m = 3;
a[0, 0] = 500;
a[0, 1] = 100;
a[0, 2] = 230;
a[1, 0] = 1000;
a[1, 1] = 300;
a[1, 2] = 100;
a[2, 0] = 200;
a[2, 1] = 1000;
a[2, 2] = 200;
}
static int maximum_sum_path( int i,
int j)
{
if (i == n - 1 && j == m - 1)
return a[i, j];
if (visited[i, j] != 0)
return dp[i, j];
visited[i, j] = 1;
int total_sum = 0;
if (i < n - 1 & j < m - 1)
{
int current_sum = Math.Max(maximum_sum_path(i, j + 1),
Math.Max(maximum_sum_path(i + 1,
j + 1),
maximum_sum_path(i + 1, j)));
total_sum = a[i, j] + current_sum;
}
else if (i == n - 1)
total_sum = a[i, j] +
maximum_sum_path(i, j + 1);
else
total_sum = a[i, j] +
maximum_sum_path(i + 1, j);
dp[i, j] = total_sum;
return total_sum;
}
public static void Main(String[] args)
{
inputMatrix();
int maximum_sum = maximum_sum_path(0, 0);
Console.WriteLine(maximum_sum);
}
}
|
Javascript
<script>
let N = 100;
let n, m;
let a = new Array(N);
let dp = new Array(N);
let visited = new Array(N);
for (let i = 0; i < N; i++)
{
a[i] = new Array(N);
dp[i] = new Array(N);
visited[i] = new Array(N);
for (let j = 0; j < N; j++)
{
a[i][j] = 0;
dp[i][j] = 0;
visited[i][j] = 0;
}
}
let current_sum = 0;
let total_sum = 0;
function inputMatrix()
{
n = 3;
m = 3;
a[0][0] = 500;
a[0][1] = 100;
a[0][2] = 230;
a[1][0] = 1000;
a[1][1] = 300;
a[1][2] = 100;
a[2][0] = 200;
a[2][1] = 1000;
a[2][2] = 200;
}
function maximum_sum_path(i, j)
{
if (i == n - 1 && j == m - 1)
return a[i][j];
if (visited[i][j] != 0)
return dp[i][j];
visited[i][j] = 1;
let total_sum = 0;
if (i < n - 1 & j < m - 1)
{
let current_sum = Math.max(
maximum_sum_path(i, j + 1),
Math.max(
maximum_sum_path(i + 1, j + 1),
maximum_sum_path(i + 1, j)));
total_sum = a[i][j] + current_sum;
}
else if (i == n - 1)
total_sum = a[i][j] + maximum_sum_path(i, j + 1);
else
total_sum = a[i][j] + maximum_sum_path(i + 1, j);
dp[i][j] = total_sum;
return total_sum;
}
inputMatrix();
let maximum_sum = maximum_sum_path(0, 0);
document.write(maximum_sum);
</script>
|
Time Complexity: O(N*M)
Auxiliary Space: O(N*M) + O(N+M) -> O(NxM) is for the declared matrix of size nxm and O(N+M) is for the stack space (maximum recursive recursion calls).
3. Tabulation approach: This approach will remove the extra space complexity i.e O(N+M) caused by recursion in the above approach.
- Declare an array of size NxM – dp[N][M].
- Traverse through the created array row-wise and start filling the values in it.
- First row of the `dp` array i.e. index (0,j) ,where j represents column, will contain the values same as the first row of the given `matrix` array.
- Otherwise, we will calculate the values for up (i-1,j), right (i,j-1) and up_left_diagonal (i-1,j-1) for the current cell and the maximum value of them will be the value for the current cell ie dp[i][j].
- Finally, the maximum path sum of the matrix will be at dp[n-1][m-1] where n=no. of rows and m=no. of columns.
C++
#include <bits/stdc++.h>
using namespace std;
int maxPathSum( int matrix[2][3], int i, int j)
{
if (i < 0 || j < 0) {
return -1000000000;
}
if (i == 0 && j == 0) {
return matrix[i][j];
}
int up = matrix[i][j] + maxPathSum(matrix, i - 1, j);
int right = matrix[i][j] + maxPathSum(matrix, i, j - 1);
int up_left_diagonal
= matrix[i][j] + maxPathSum(matrix, i - 1, j - 1);
return max(up, max(right, up_left_diagonal));
}
int main()
{
int matrix[2][3]
= { { 100, -350, -200 }, { -100, -300, 700 } };
cout << maxPathSum(matrix, 1, 2) << endl;
return 0;
}
|
Java
import java.io.*;
class GFG {
public static void main(String[] args)
{
int matrix [][] = {{ 100 , - 350 , - 200 }, {- 100 , - 300 , 700 }};
int n = matrix.length;
int m = matrix[ 0 ].length;
int dp[][] = new int [n][m], up, right, up_left_diagonal;
for ( int i= 0 ; i<n; i++){
for ( int j= 0 ; j<m; j++){
if (i== 0 ) {
dp[i][j] = matrix[i][j];
}
else {
up = matrix[i][j];
if (i> 0 ) up += dp[i- 1 ][j];
else up -= ( int )Math.pow( 10 , 9 );
right = matrix[i][j];
if (j> 0 ) right += dp[i][j- 1 ];
else right -= ( int )Math.pow( 10 , 9 );
up_left_diagonal = matrix[i][j];
if (i> 0 && j> 0 ) up_left_diagonal += dp[i- 1 ][j- 1 ];
else up_left_diagonal -= ( int )Math.pow( 10 , 9 );
dp[i][j] = Math.max(up , Math.max( right, up_left_diagonal));
}
}
}
System.out.println(dp[n- 1 ][m- 1 ]);
}
}
|
Python3
def maxPathSum(matrix, i, j):
if i < 0 or j < 0 :
return - 1000000000
if i = = 0 and j = = 0 :
return matrix[i][j]
up = matrix[i][j] + maxPathSum(matrix, i - 1 , j)
right = matrix[i][j] + maxPathSum(matrix, i, j - 1 )
up_left_diagonal = matrix[i][j] + maxPathSum(matrix, i - 1 , j - 1 )
return max (up, max (right, up_left_diagonal))
matrix = [[ 100 , - 350 , - 200 ], [ - 100 , - 300 , 700 ]]
print (maxPathSum(matrix, 1 , 2 ))
|
C#
using System;
class GFG
{
public static int maxPathSum( int [,] matrix, int i, int j)
{
if (i<0 || j<0) {
return -1000000000;
}
if (i==0 && j==0) {
return matrix[i,j];
}
int up = matrix[i,j] + maxPathSum(matrix, i - 1, j);
int right = matrix[i,j] + maxPathSum(matrix, i, j - 1);
int up_left_diagonal = matrix[i,j] + maxPathSum(matrix, i - 1, j - 1);
return Math.Max(up , Math.Max( right, up_left_diagonal));
}
public static void Main( string [] args)
{
int [,] matrix = {{100, -350, -200}, {-100, -300, 700}};
Console.Write(maxPathSum(matrix, 1, 2));
}
}
|
Javascript
function maxPathSum(matrix, i, j) {
if (i < 0 || j < 0) {
return -1000000000;
}
if (i === 0 && j === 0) {
return matrix[i][j];
}
const up = matrix[i][j] + maxPathSum(matrix, i - 1, j);
const right = matrix[i][j] + maxPathSum(matrix, i, j - 1);
const up_left_diagonal = matrix[i][j] + maxPathSum(matrix, i - 1, j - 1);
return Math.max(up, Math.max(right, up_left_diagonal));
}
const matrix = [[100, -350, -200], [-100, -300, 700]];
console.log(maxPathSum(matrix, 1, 2));
|
Time complexity: O(NxM)
Auxiliary Space: O(NxM)
Last Updated :
02 Mar, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...