Open In App
Related Articles

Maximum path sum that starting with any cell of 0-th row and ending with any cell of (N-1)-th row

Improve Article
Improve
Save Article
Save
Like Article
Like

Given a N X N matrix Mat[N][N] of positive integers. There are only three possible moves from a cell (i, j) 

  1. (i+1, j)
  2. (i+1, j-1)
  3. (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 we reached the first row of the matrix, return the
    // value of that element
    if (i == N - 1 && j == N - 1)
        return Mat[i][j];
 
    // Out of matrix bound
    if (i >= N || i < 0
 
        || j >= N || j < 0)
        return 0;
 
    // Call all the rest positions that we reached from the
    // current position and find the maximum between them
    // and add the current value in that path
    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()
{
    // Example usage
    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]
 
# Example usage
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 we reached the last row of the matrix, return the
        // value of that element
        if (i == N - 1 && j == N - 1)
            return mat[i][j];
 
        // Out of matrix bound
        if (i >= N || i < 0 || j >= N || j < 0)
            return 0;
 
        // Call all the rest positions that we reached from the
        // current position and find the maximum between them
        // and add the current value in that path
        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()
    {
        // Example usage
        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 we reached the first row of the matrix, return the value of that element
    if (i === N - 1 && j === N - 1)
        return Mat[i][j];
 
    // Out of matrix bound
    if (i >= N || i < 0 || j >= N || j < 0)
        return 0;
 
    // Call all the rest positions that we reached from the
    // current position and find the maximum between them
    // and add the current value in that path
    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() {
    // Example usage
    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 we reached the first row of the matrix, return the
    // value of that element
    if (i == N - 1 && j == N - 1)
        return Mat[i][j];
 
    // Out of matrix bound
    if (i >= N || i < 0
 
        || j >= N || j < 0)
        return 0;
 
    if (dp[i][j] != -1)
        return dp[i][j];
 
    // Call all the rest positions that we reached from the
    // current position and find the maximum between them
    // and add the current value in that path
    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()
{
    // Example usage
    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]
 
 
# Example usage
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 we reached the first row of the matrix, return the
    // value of that element
        if (i == n - 1 && j == n - 1)
            return matrix[i][j];
    // Out of matrix bound
        if (i >= n || i < 0 || j >= n || j < 0)
            return 0;
        if (dp[i, j] != -1)
            return dp[i, j];
    // Call all the rest positions that we reached from the
    // current position and find the maximum between them
    // and add the current value in that path
        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)
    {   // Example usage
        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;
 
    // Base case: If we reach the bottom-right corner, return the matrix value.
    if (i === n - 1 && j === n - 1) {
        return matrix[i][j];
    }
 
    // Base case: If we go out of bounds, return 0.
    if (i >= n || i < 0 || j >= n || j < 0) {
        return 0;
    }
 
    // If the value has already been calculated, return it from dp array.
    if (dp[i][j] !== -1) {
        return dp[i][j];
    }
 
    // Calculate the maximum path by recursively exploring three directions.
    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)
    );
 
    // Store the result in the dp array and return it.
    dp[i][j] = maxPath + matrix[i][j];
 
    return dp[i][j];
}
 
// Example usage
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++




// C++ program to find Maximum path sum
// start any column in row '0' and ends
// up to any column in row 'n-1'
#include<bits/stdc++.h>
using namespace std;
#define N 4
 
// function find maximum sum path
int MaximumPath(int Mat[][N])
{
    int result = 0 ;
 
    // create 2D matrix to store the sum
    // of the path
    int dp[N][N+2];
 
    // initialize all dp matrix as '0'
    memset(dp, 0, sizeof(dp));
 
    // copy all element of first row into
    // 'dp' first row
    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] ;
 
    // Find maximum path sum that end ups
    // at  any column of last row 'N-1'
    for (int i=0; i<=N; i++)
        result = max(result, dp[N-1][i]);
 
    // return maximum sum path
    return result ;
}
 
// driver program to test above function
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




// Java program to find Maximum path sum
// start any column in row '0' and ends
// up to any column in row 'n-1'
import java.util.*;
 
public class GFG {
     
    private static int N = 4;
 
    // function find maximum sum path
    private static int maximumPath(int Mat[][]){
        int result = 0;
 
        // create 2D matrix to store the sum
        // of the path
        int dp[][] = new int[N][N + 2];
 
        // copy all element of first row into
        // 'dp' first row
        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];
 
        // Find maximum path sum that end ups
        // at any column of last row 'N-1'
        for (int i = 0; i <= N; i++)
            result = Math.max(result, dp[N - 1][i]);
 
        // return maximum sum path
        return result;
    }
     
    // driver code
    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));
    }
}
 
// This code is contributed by Anant Agarwal.


Python3




# Python3 program to find
# Maximum path sum
# start any column in
# row '0' and ends
# up to any column in row 'n-1'
 
N = 4
 
# function find maximum sum path
def MaximumPath(Mat):
 
    result = 0
 
    # create 2D matrix to store the sum
    # of the path
    # initialize all dp matrix as '0'
    dp = [[0 for i in range(N+2)] for j in range(N)]
 
    # copy all element of first row into
    # dp first row
    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]
 
    # Find maximum path sum that end ups
    # at any column of last row 'N-1'
    for i in range(N+1):
        result = max(result, dp[N-1][i])
 
    # return maximum sum path
    return result
 
# driver program to test above function
Mat = [[4, 2, 3, 4],
       [2, 9, 1, 10],
       [15, 1, 3, 0],
       [16, 92, 41, 44]]
 
print(MaximumPath(Mat))
 
# This code is contributed by Soumen Ghosh.


C#




// C# program to find Maximum path sum
// start any column in row '0' and ends
// up to any column in row 'n-1'
using System;
 
class GFG {
     
    static int N = 4;
 
    // function find maximum sum path
    static int MaximumPath(int [,] Mat)
    {
        int result = 0;
 
        // create 2D matrix to store the sum
        // of the path
        int [,]dp = new int[N,N + 2];
 
        // initialize all dp matrix as '0'
        //for (int[] rows : dp)
        //    Arrays.fill(rows, 0);
 
        // copy all element of first row into
        // 'dp' first row
        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];
 
        // Find maximum path sum that end ups
        // at any column of last row 'N-1'
        for (int i = 0; i <= N; i++)
            result = Math.Max(result, dp[N - 1,i]);
 
        // return maximum sum path
        return result;
    }
     
    // driver code
    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));
    }
}
 
// This code is contributed by Ryuga.


Javascript




<script>
 
// Javascript program to find Maximum path sum
// start any column in row '0' and ends
// up to any column in row 'n-1'
     
    let N = 4;
     
    // function find maximum sum path
    function MaximumPath(Mat)
    {
        let result = 0;
   
        // create 2D matrix to store the sum
        // of the path
        let dp = new Array(N);
         
        // initialize all dp matrix as '0'
        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;
            }
        }
         
   
        // copy all element of first row into
        // 'dp' first row
        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];
   
        // Find maximum path sum that end ups
        // at any column of last row 'N-1'
        for (let i = 0; i <= N; i++)
            result = Math.max(result, dp[N - 1][i]);
   
        // return maximum sum path
        return result;
    }
     
    // driver code
    let Mat = [[4, 2, 3, 4],
       [2, 9, 1, 10],
       [15, 1, 3, 0],
       [16, 92, 41, 44]]
    document.write(MaximumPath(Mat))
      
    // This code is contributed by rag2127
     
</script>


PHP




<?php
// PHP program to find Maximum path sum
// start any column in row '0' and ends
// up to any column in row 'n-1'
$N = 4;
 
// function find maximum sum path
function MaximumPath(&$Mat)
{
    global $N;
    $result = 0;
 
    // create 2D matrix to store the sum
    // of the path
    $dp = array_fill(0, $N,
          array_fill(0, $N + 2, NULL));
 
    // copy all element of first row
    // into 'dp' first row
    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] ;
 
    // Find maximum path sum that end ups
    // at any column of last row 'N-1'
    for ($i = 0; $i <= $N; $i++)
        $result = max($result, $dp[$N - 1][$i]);
 
    // return maximum sum path
    return $result ;
}
 
// Driver Code
$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" ;
 
// This code is contributed by ita_c
?>


Output

120







Time complexity : O(N2)
Auxiliary space: O(N2)

If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks. 


Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!

Last Updated : 17 Oct, 2023
Like Article
Save Article
Previous
Next
Similar Reads
Complete Tutorials