Maximum path sum that starting with any cell of 0-th row and ending with any cell of (N-1)-th row
Last Updated :
17 Oct, 2023
Given a N X N matrix Mat[N][N] of positive integers. There are only three possible moves from a cell (i, j)
- (i+1, j)
- (i+1, j-1)
- (i+1, j+1)
Starting from any column in row 0, return the largest sum of any of the paths up to row N-1.
Examples:
Input : mat[4][4] = { {4, 2, 3, 4},
{2, 9, 1, 10},
{15, 1, 3, 0},
{16, 92, 41, 44} };
Output :120
path : 4 + 9 + 15 + 92 = 120
Asked in: Amazon interview
The above problem can be recursively defined.
Let initial position be MaximumPathSum(N-1, j), where j varies from 0 to N-1. We return maximum value between all path that we start traversing (N-1, j) [ where j varies from 0 to N-1]
i = N-1, j = 0 to N -1
int MaximumPath(Mat[][N], I, j)
// IF we reached to first row of
// matrix then return value of that
// element
IF ( i == 0 && j = 0 )
return Mat[i][j]
// out of matrix bound
IF( i = N || j < 0 )
return 0;
// call all rest position that we reached
// from current position and find maximum
// between them and add current value in
// that path
return max(MaximumPath(Mat, i-1, j),
MaximumPath(Mat, i-1, j-1),
MaximumPath(Mat, i-1, j+1)))
+ Mat[i][j];
Implementation of naive recursion code:
C++
#include <algorithm> // Required for std::max
#include <iostream>
#include <vector>
int MaximumPath(std::vector<std::vector< int > >& Mat, int i,
int j)
{
int N = Mat.size();
if (i == N - 1 && j == N - 1)
return Mat[i][j];
if (i >= N || i < 0
|| j >= N || j < 0)
return 0;
return std::max(
std::max(MaximumPath(Mat, i + 1, j),
MaximumPath(Mat, i + 1, j - 1)),
MaximumPath(Mat, i + 1, j + 1))
+ Mat[i][j];
}
int main()
{
std::vector<std::vector< int > > matrix
= { { 4, 2, 3, 4 },
{ 2, 9, 1, 10 },
{ 15, 1, 3, 0 },
{ 16, 92, 41, 44 } };
int N = matrix.size();
int result = MaximumPath(matrix, 0, 0);
std::cout << "Maximum Path Sum: " << result
<< std::endl;
return 0;
}
|
Java
import java.util.*;
class Main {
public static int maximumPath( int [][] mat, int i, int j) {
int N = mat.length;
if (i == N - 1 && j == N - 1 )
return mat[i][j];
if (i >= N || i < 0 || j >= N || j < 0 )
return 0 ;
return Math.max(
Math.max(maximumPath(mat, i + 1 , j), maximumPath(mat, i + 1 , j - 1 )),
maximumPath(mat, i + 1 , j + 1 ))
+ mat[i][j];
}
public static void main(String[] args) {
int [][] matrix = {
{ 4 , 2 , 3 , 4 },
{ 2 , 9 , 1 , 10 },
{ 15 , 1 , 3 , 0 },
{ 16 , 92 , 41 , 44 }
};
int N = matrix.length;
int result = maximumPath(matrix, 0 , 0 );
System.out.println( "Maximum Path Sum: " + result);
}
}
|
Python3
def maximum_path(mat, i, j):
n = len (mat)
if i = = n - 1 and j = = n - 1 :
return mat[i][j]
if i > = n or i < 0 or j > = n or j < 0 :
return 0
return max (maximum_path(mat, i + 1 , j),
maximum_path(mat, i + 1 , j - 1 ),
maximum_path(mat, i + 1 , j + 1 )) + mat[i][j]
matrix = [[ 4 , 2 , 3 , 4 ],
[ 2 , 9 , 1 , 10 ],
[ 15 , 1 , 3 , 0 ],
[ 16 , 92 , 41 , 44 ]]
result = maximum_path(matrix, 0 , 0 )
print ( "Maximum Path Sum:" , result)
|
C#
using System;
public class GFG
{
public static int MaximumPath( int [][] mat, int i, int j)
{
int N = mat.Length;
if (i == N - 1 && j == N - 1)
return mat[i][j];
if (i >= N || i < 0 || j >= N || j < 0)
return 0;
return Math.Max(
Math.Max(MaximumPath(mat, i + 1, j),
MaximumPath(mat, i + 1, j - 1)),
MaximumPath(mat, i + 1, j + 1))
+ mat[i][j];
}
public static void Main()
{
int [][] matrix =
{
new int [] { 4, 2, 3, 4 },
new int [] { 2, 9, 1, 10 },
new int [] { 15, 1, 3, 0 },
new int [] { 16, 92, 41, 44 }
};
int N = matrix.Length;
int result = MaximumPath(matrix, 0, 0);
Console.WriteLine( "Maximum Path Sum: " + result);
}
}
|
Javascript
function MaximumPath(Mat, i, j) {
const N = Mat.length;
if (i === N - 1 && j === N - 1)
return Mat[i][j];
if (i >= N || i < 0 || j >= N || j < 0)
return 0;
return Math.max(
Math.max(MaximumPath(Mat, i + 1, j),
MaximumPath(Mat, i + 1, j - 1)),
MaximumPath(Mat, i + 1, j + 1))
+ Mat[i][j];
}
function main() {
const matrix = [
[4, 2, 3, 4],
[2, 9, 1, 10],
[15, 1, 3, 0],
[16, 92, 41, 44]
];
const N = matrix.length;
const result = MaximumPath(matrix, 0, 0);
console.log( "Maximum Path Sum: " + result);
}
main();
|
Output
Maximum Path Sum: 120
Time complexity : O(2N)
Auxiliary space: O(N)
Memoization DP:
In memoization DP, we introduced a dp table, which is a 2D vector of integers. The dp table is initialized with -1 to indicate that the results for each cell in the matrix haven’t been calculated yet.
During the recursive calls to the MaximumPath function, we check if the result for the current position (i, j) is already memoized in the dp table. If it is, we return the memoized result instead of recalculating it.
After calculating the maximum path sum for a position (i, j), we store the result in the corresponding cell of the dp table dp[i][j]. This way, we avoid redundant calculations for the same position and improve the efficiency of the algorithm.
Using memoization with a DP table helps reduce the time complexity of the algorithm by avoiding unnecessary recursive calls and reusing previously calculated results. It ensures that each subproblem is solved only once, leading to a more efficient solution for larger matrices.
C++
#include <algorithm> // Required for std::max
#include <iostream>
#include <vector>
int MaximumPath(std::vector<std::vector< int > >& Mat, int i,
int j, std::vector<std::vector< int > >& dp)
{
int N = Mat.size();
if (i == N - 1 && j == N - 1)
return Mat[i][j];
if (i >= N || i < 0
|| j >= N || j < 0)
return 0;
if (dp[i][j] != -1)
return dp[i][j];
return dp[i][j]
= std::max(
std::max(
MaximumPath(Mat, i + 1, j, dp),
MaximumPath(Mat, i + 1, j - 1, dp)),
MaximumPath(Mat, i + 1, j + 1, dp))
+ Mat[i][j];
}
int main()
{
std::vector<std::vector< int > > matrix
= { { 4, 2, 3, 4 },
{ 2, 9, 1, 10 },
{ 15, 1, 3, 0 },
{ 16, 92, 41, 44 } };
int N = matrix.size();
std::vector<std::vector< int > > dp(
N, std::vector< int >(N, -1));
int result = MaximumPath(matrix, 0, 0, dp);
std::cout << "Maximum Path Sum: " << result
<< std::endl;
return 0;
}
|
Java
import java.util.Arrays;
import java.util.List;
public class MaximumPathSum {
public static int maximumPath(List<List<Integer>> matrix, int i, int j, int [][] dp) {
int n = matrix.size();
if (i == n - 1 && j == n - 1 )
return matrix.get(i).get(j);
if (i >= n || i < 0 || j >= n || j < 0 )
return 0 ;
if (dp[i][j] != - 1 )
return dp[i][j];
int maxPath = Math.max(Math.max(maximumPath(matrix, i + 1 , j, dp),
maximumPath(matrix, i + 1 , j - 1 , dp)),
maximumPath(matrix, i + 1 , j + 1 , dp));
dp[i][j] = maxPath + matrix.get(i).get(j);
return dp[i][j];
}
public static void main(String[] args) {
List<List<Integer>> matrix = Arrays.asList(
Arrays.asList( 4 , 2 , 3 , 4 ),
Arrays.asList( 2 , 9 , 1 , 10 ),
Arrays.asList( 15 , 1 , 3 , 0 ),
Arrays.asList( 16 , 92 , 41 , 44 )
);
int n = matrix.size();
int [][] dp = new int [n][n];
for ( int [] row : dp) {
Arrays.fill(row, - 1 );
}
int result = maximumPath(matrix, 0 , 0 , dp);
System.out.println( "Maximum Path Sum: " + result);
}
}
|
Python3
def maximum_path(matrix, i, j, dp):
n = len (matrix)
if i = = n - 1 and j = = n - 1 :
return matrix[i][j]
if i > = n or i < 0 or j > = n or j < 0 :
return 0
if dp[i][j] ! = - 1 :
return dp[i][j]
max_path = max (
max (maximum_path(matrix, i + 1 , j, dp),
maximum_path(matrix, i + 1 , j - 1 , dp)),
maximum_path(matrix, i + 1 , j + 1 , dp))
dp[i][j] = max_path + matrix[i][j]
return dp[i][j]
matrix = [[ 4 , 2 , 3 , 4 ],
[ 2 , 9 , 1 , 10 ],
[ 15 , 1 , 3 , 0 ],
[ 16 , 92 , 41 , 44 ]]
n = len (matrix)
dp = [[ - 1 ] * n for _ in range (n)]
result = maximum_path(matrix, 0 , 0 , dp)
print ( "Maximum Path Sum:" , result)
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
public static int MaximumPath(List<List< int >> matrix, int i, int j, int [,] dp)
{
int n = matrix.Count;
if (i == n - 1 && j == n - 1)
return matrix[i][j];
if (i >= n || i < 0 || j >= n || j < 0)
return 0;
if (dp[i, j] != -1)
return dp[i, j];
int maxPath = Math.Max(Math.Max(MaximumPath(matrix, i + 1, j, dp),
MaximumPath(matrix, i + 1, j - 1, dp)),
MaximumPath(matrix, i + 1, j + 1, dp));
dp[i, j] = maxPath + matrix[i][j];
return dp[i, j];
}
public static void Main( string [] args)
{
List<List< int >> matrix = new List<List< int >>()
{
new List< int >() { 4, 2, 3, 4 },
new List< int >() { 2, 9, 1, 10 },
new List< int >() { 15, 1, 3, 0 },
new List< int >() { 16, 92, 41, 44 }
};
int n = matrix.Count;
int [,] dp = new int [n, n];
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < n; j++)
{
dp[i, j] = -1;
}
}
int result = MaximumPath(matrix, 0, 0, dp);
Console.WriteLine( "Maximum Path Sum: " + result);
}
}
|
Javascript
function maximum_path(matrix, i, j, dp) {
const n = matrix.length;
if (i === n - 1 && j === n - 1) {
return matrix[i][j];
}
if (i >= n || i < 0 || j >= n || j < 0) {
return 0;
}
if (dp[i][j] !== -1) {
return dp[i][j];
}
const maxPath = Math.max(
maximum_path(matrix, i + 1, j, dp),
maximum_path(matrix, i + 1, j - 1, dp),
maximum_path(matrix, i + 1, j + 1, dp)
);
dp[i][j] = maxPath + matrix[i][j];
return dp[i][j];
}
const matrix = [
[4, 2, 3, 4],
[2, 9, 1, 10],
[15, 1, 3, 0],
[16, 92, 41, 44]
];
const n = matrix.length;
const dp = Array.from({ length: n }, () => Array(n).fill(-1));
const result = maximum_path(matrix, 0, 0, dp);
console.log( "Maximum Path Sum:" , result);
|
Output
Maximum Path Sum: 120
Time complexity : O(N2)
Auxiliary space: O(N2)
Tabulation DP:
If we draw recursion tree of above recursive solution, we can observe overlapping subproblems.
Since the problem has overlapping subproblems, we can solve it efficiently using Dynamic Programming. Below is Dynamic Programming based solution.
Implementation:
C++
#include<bits/stdc++.h>
using namespace std;
#define N 4
int MaximumPath( int Mat[][N])
{
int result = 0 ;
int dp[N][N+2];
memset (dp, 0, sizeof (dp));
for ( int i = 0 ; i < N ; i++)
dp[0][i+1] = Mat[0][i];
for ( int i = 1 ; i < N ; i++)
for ( int j = 1 ; j <= N ; j++)
dp[i][j] = max(dp[i-1][j-1],
max(dp[i-1][j],
dp[i-1][j+1])) +
Mat[i][j-1] ;
for ( int i=0; i<=N; i++)
result = max(result, dp[N-1][i]);
return result ;
}
int main()
{
int Mat[4][4] = { { 4, 2 , 3 , 4 },
{ 2 , 9 , 1 , 10},
{ 15, 1 , 3 , 0 },
{ 16 ,92, 41, 44 }
};
cout << MaximumPath ( Mat ) <<endl ;
return 0;
}
|
Java
import java.util.*;
public class GFG {
private static int N = 4 ;
private static int maximumPath( int Mat[][]){
int result = 0 ;
int dp[][] = new int [N][N + 2 ];
for ( int i = 0 ; i < N; i++)
dp[ 0 ][i + 1 ] = Mat[ 0 ][i];
for ( int i = 1 ; i < N; i++)
for ( int j = 1 ; j <= N; j++)
dp[i][j] = Math.max(dp[i - 1 ][j - 1 ],
Math.max(dp[i - 1 ][j],
dp[i - 1 ][j + 1 ])) +
Mat[i][j - 1 ];
for ( int i = 0 ; i <= N; i++)
result = Math.max(result, dp[N - 1 ][i]);
return result;
}
public static void main(String arg[]){
int Mat[][] = { { 4 , 2 , 3 , 4 },
{ 2 , 9 , 1 , 10 },
{ 15 , 1 , 3 , 0 },
{ 16 , 92 , 41 , 44 } };
System.out.println(maximumPath(Mat));
}
}
|
Python3
N = 4
def MaximumPath(Mat):
result = 0
dp = [[ 0 for i in range (N + 2 )] for j in range (N)]
for i in range (N):
for j in range ( 1 , N + 1 ):
dp[i][j] = max (dp[i - 1 ][j - 1 ],
max (dp[i - 1 ][j],
dp[i - 1 ][j + 1 ])) + \
Mat[i][j - 1 ]
for i in range (N + 1 ):
result = max (result, dp[N - 1 ][i])
return result
Mat = [[ 4 , 2 , 3 , 4 ],
[ 2 , 9 , 1 , 10 ],
[ 15 , 1 , 3 , 0 ],
[ 16 , 92 , 41 , 44 ]]
print (MaximumPath(Mat))
|
C#
using System;
class GFG {
static int N = 4;
static int MaximumPath( int [,] Mat)
{
int result = 0;
int [,]dp = new int [N,N + 2];
for ( int i = 0; i < N; i++)
dp[0,i + 1] = Mat[0,i];
for ( int i = 1; i < N; i++)
for ( int j = 1; j <= N; j++)
dp[i,j] = Math.Max(dp[i - 1,j - 1],
Math.Max(dp[i - 1,j],
dp[i - 1,j + 1])) +
Mat[i,j - 1];
for ( int i = 0; i <= N; i++)
result = Math.Max(result, dp[N - 1,i]);
return result;
}
public static void Main()
{
int [,]Mat = { { 4, 2, 3, 4 },
{ 2, 9, 1, 10 },
{ 15, 1, 3, 0 },
{ 16, 92, 41, 44 } };
Console.WriteLine(MaximumPath(Mat));
}
}
|
Javascript
<script>
let N = 4;
function MaximumPath(Mat)
{
let result = 0;
let dp = new Array(N);
for (let i=0;i<N;i++)
{
dp[i]= new Array(N+2);
for (let j=0;j<N+2;j++)
{
dp[i][j]=0;
}
}
for (let i = 0; i < N; i++)
dp[0][i + 1] = Mat[0][i];
for (let i = 1; i < N; i++)
for (let j = 1; j <= N; j++)
dp[i][j] = Math.max(dp[i - 1][j - 1],
Math.max(dp[i - 1][j],
dp[i - 1][j + 1])) +
Mat[i][j - 1];
for (let i = 0; i <= N; i++)
result = Math.max(result, dp[N - 1][i]);
return result;
}
let Mat = [[4, 2, 3, 4],
[2, 9, 1, 10],
[15, 1, 3, 0],
[16, 92, 41, 44]]
document.write(MaximumPath(Mat))
</script>
|
PHP
<?php
$N = 4;
function MaximumPath(& $Mat )
{
global $N ;
$result = 0;
$dp = array_fill (0, $N ,
array_fill (0, $N + 2, NULL));
for ( $i = 0 ; $i < $N ; $i ++)
$dp [0][ $i + 1] = $Mat [0][ $i ];
for ( $i = 1 ; $i < $N ; $i ++)
for ( $j = 1 ; $j <= $N ; $j ++)
$dp [ $i ][ $j ] = max( $dp [ $i - 1][ $j - 1],
max( $dp [ $i - 1][ $j ],
$dp [ $i - 1][ $j + 1])) +
$Mat [ $i ][ $j - 1] ;
for ( $i = 0; $i <= $N ; $i ++)
$result = max( $result , $dp [ $N - 1][ $i ]);
return $result ;
}
$Mat = array ( array (4, 2 , 3 , 4),
array (2 , 9 , 1 , 10),
array (15, 1 , 3 , 0),
array (16 ,92, 41, 44));
echo MaximumPath ( $Mat ) . "\n" ;
?>
|
Time complexity : O(N2)
Auxiliary space: O(N2)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...