Maximum sum of a path in a Right Number Triangle
Last Updated :
02 Feb, 2023
Given a right triangle of numbers, find the largest of the sum of numbers that appear on the paths starting from the top towards the base, so that on each path the next number is located directly below or below and one place to the right.
Examples :
Input : 1
1 2
4 1 2
2 3 1 1
Output : 9
Explanation : 1 + 1 + 4 + 3
Input : 2
4 1
1 2 7
Output : 10
Explanation : 2 + 1 + 7
Method 1: Recursion
The idea is to find the largest sum ending at every cell of the last row and return a maximum of these sums. We can recursively compute these sums by recursively considering the above two cells.
C++
#include <bits/stdc++.h>
using namespace std;
int helper(vector<vector< int >>& tri, int i, int j){
if (i == tri.size() ){
return 0 ;
}
int mx ;
mx = tri[i][j] + max(helper(tri, i+1,j), helper(tri,i+1, j+1)) ;
return mx ;
}
int maxSumPath(vector<vector< int >>& tri) {
return helper(tri, 0, 0) ;
}
int main()
{
vector<vector< int > > tri{ { 1 },
{ 2, 1 },
{ 3, 3, 2 } };
cout << maxSumPath(tri);
return 0;
}
|
Java
import java.io.*;
class GFG
{
public static int helper( int tri[][], int i, int j)
{
if (i == tri.length) {
return 0 ;
}
int mx;
mx = tri[i][j]
+ Math.max(helper(tri, i + 1 , j),
helper(tri, i + 1 , j + 1 ));
return mx;
}
public static int maxSumPath( int tri[][])
{
return helper(tri, 0 , 0 );
}
public static void main(String[] args)
{
int tri[][] = { { 1 }, { 2 , 1 }, { 3 , 3 , 2 } };
System.out.print(maxSumPath(tri));
}
}
|
Python3
def helper(tri, i, j):
if (i = = len (tri)):
return 0
mx = 0
mx = tri[i][j] + max (helper(tri, i + 1 , j), helper(tri, i + 1 , j + 1 ))
return mx
def maxSumPath(tri):
return helper(tri, 0 , 0 )
if __name__ = = "__main__" :
tri = [[ 1 ], [ 2 , 1 ], [ 3 , 3 , 2 ]]
print (maxSumPath(tri))
|
C#
using System;
public class GFG {
static int helper( int [][] tri, int i, int j)
{
if (i == tri.GetLength(0)) {
return 0;
}
int mx;
mx = tri[i][j]
+ Math.Max(helper(tri, i + 1, j),
helper(tri, i + 1, j + 1));
return mx;
}
static int maxSumPath( int [][] tri)
{
return helper(tri, 0, 0);
}
static public void Main()
{
int [][] tri = { new int [] { 1 }, new int [] { 2, 1 },
new int [] { 3, 3, 2 } };
Console.Write(maxSumPath(tri));
}
}
|
Javascript
function helper(tri, i, j)
{
if (i == tri.length ){
return 0 ;
}
let mx ;
mx = tri[i][j] + Math.max(helper(tri, i+1,j), helper(tri,i+1, j+1)) ;
return mx ;
}
function maxSumPath( tri) {
return helper(tri, 0, 0) ;
}
let tri = [[ 1 ], [ 2, 1 ],[ 3, 3, 2 ]];
console.log(maxSumPath(tri));
|
Complexity Analysis:
- Time Complexity: O(2N*N) where N = number of rows and M = number of columns
- Auxiliary Space: O(N)
Method 2: Dynamic Programming – Top-Down Approach
Since there are overlapping subproblems, we use dynamic programming to find the maximum sum ending at a particular cell of the last row.
Below is the implementation of the above idea.
C++
#include <bits/stdc++.h>
using namespace std;
int helper(vector<vector< int >>& tri, int i, int j, vector<vector< int >>& dp){
if (i == tri.size() ){
return 0 ;
}
if (dp[i][j] != -1){
return dp[i][j] ;
}
return dp[i][j] = tri[i][j] + max(helper(tri, i+1,j, dp), helper(tri,i+1, j+1, dp)) ;
}
int maxSumPath(vector<vector< int >>& tri) {
int n = tri.size() ;
vector<vector< int >> dp(n, vector< int >(n, -1) ) ;
return helper(tri, 0, 0, dp) ;
}
int main()
{
vector<vector< int > > tri{ { 1 },
{ 2, 1 },
{ 3, 3, 2 } };
cout << maxSumPath(tri);
return 0;
}
|
Java
import java.io.*;
class GFG {
static int helper( int [][] tri, int i, int j, int [][] dp)
{
if (i == tri.length) {
return 0 ;
}
if (dp[i][j] != - 1 ) {
return dp[i][j];
}
return dp[i][j]
= tri[i][j]
+ Math.max(helper(tri, i + 1 , j, dp),
helper(tri, i + 1 , j + 1 , dp));
}
static int maxSumPath( int [][] tri)
{
int n = tri.length;
int [][] dp = new int [n][n];
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < n; j++) {
dp[i][j] = - 1 ;
}
}
return helper(tri, 0 , 0 , dp);
}
public static void main(String[] args)
{
int [][] tri = { { 1 }, { 2 , 1 }, { 3 , 3 , 2 } };
System.out.print(maxSumPath(tri));
}
}
|
Python3
def helper(tri, i, j, dp):
if (i = = len (tri)):
return 0
if (dp[i][j] ! = - 1 ):
return dp[i][j]
dp[i][j] = tri[i][j] + max (helper(tri, i + 1 ,j, dp), helper(tri, i + 1 , j + 1 , dp))
return dp[i][j];
def maxSumPath(tri):
n = len (tri) ;
dp = [[ - 1 ] * n for _ in range (n)]
return helper(tri, 0 , 0 , dp)
if __name__ = = "__main__" :
tri = [[ 1 ],[ 2 , 1 ],[ 3 , 3 , 2 ] ];
print (maxSumPath(tri));
|
C#
using System;
class GFG
{
static int helper( int [][] tri, int i, int j, int [, ] dp)
{
if (i == tri.GetLength(0))
return 0;
if (dp[i, j] != -1) {
return dp[i, j];
}
return dp[i, j]
= tri[i][j]
+ Math.Max(helper(tri, i + 1, j, dp),
helper(tri, i + 1, j + 1, dp));
}
static int maxSumPath( int [][] tri)
{
int n = tri.Length;
int [, ] dp = new int [n, n];
for ( int i = 0; i < n; i++)
for ( int j = 0; j < n; j++)
dp[i, j] = -1;
return helper(tri, 0, 0, dp);
}
static void Main()
{
int [][] tri = new int [3][];
tri[0] = new int [] { 1 };
tri[1] = new int [] { 2, 1 };
tri[2] = new int [] { 3, 3, 2 };
Console.Write(maxSumPath(tri));
}
}
|
Javascript
function helper( tri, i, j, dp)
{
if (i == tri.length ){
return 0 ;
}
if (dp[i][j] != -1){
return dp[i][j] ;
}
return dp[i][j] = tri[i][j] + Math.max(helper(tri, i+1,j, dp), helper(tri,i+1, j+1, dp)) ;
}
function maxSumPath( tri) {
let n = tri.length ;
let dp= new Array(n);
for (let i = 0; i < n; i++)
dp[i] = new Array(n);
for (let i = 0; i < n; i++)
for (let j = 0; j < n; j++)
dp[i][j] = -1;
return helper(tri, 0, 0, dp) ;
}
let tri = [[ 1 ], [ 2, 1 ], [ 3, 3, 2 ]];
console.log(maxSumPath(tri));
|
Complexity Analysis:
- Time Complexity: O(N*M) where N = number of rows and M = number of columns
- Auxiliary Space: O(N2)
Method 3: Dynamic Programming: Bottom-Up Approach
Since there are overlapping subproblems, we use dynamic programming to find the maximum sum ending at a particular cell of the last row. Below is the implementation of the above idea.
C++
#include <bits/stdc++.h>
using namespace std;
int helper(vector<vector< int >>& tri, int i, int j, vector<vector< int >>& dp){
int n = tri.size() ;
for ( int j = 0; j < n; j++ ){
dp[n-1][j] = tri[n-1][j] ;
}
for ( int i = n-2; i >= 0; i--){
for ( int j = i; j >= 0; j-- ){
dp[i][j] = tri[i][j] + max(dp[i+1][j] , dp[i+1][j+1]) ;
}
}
return dp[0][0] ;
}
int maxSumPath(vector<vector< int >>& tri) {
int n = tri.size() ;
vector<vector< int >> dp(n, vector< int >(n, -1) ) ;
return helper(tri, 0, 0, dp) ;
}
int main()
{
vector<vector< int > > tri{ { 1 },
{ 2, 1 },
{ 3, 3, 2 } };
cout << maxSumPath(tri);
return 0;
}
|
Java
import java.util.*;
class GFG {
static int helper( int [][] tri, int i, int j, int [][] dp)
{
int n = tri.length;
for (j = 0 ; j < n; j++) {
dp[n - 1 ][j] = tri[n - 1 ][j];
}
for (i = n - 2 ; i >= 0 ; i--) {
for (j = i; j >= 0 ; j--) {
dp[i][j] = tri[i][j]
+ Math.max(dp[i + 1 ][j],
dp[i + 1 ][j + 1 ]);
}
}
return dp[ 0 ][ 0 ];
}
static int maxSumPath( int [][] tri)
{
int n = tri.length;
int [][] dp = new int [n][n];
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < n; j++) {
dp[i][j] = - 1 ;
}
}
return helper(tri, 0 , 0 , dp);
}
public static void main(String[] args)
{
int [][] tri = { { 1 }, { 2 , 1 }, { 3 , 3 , 2 } };
System.out.println(maxSumPath(tri));
}
}
|
Python3
import math
def helper(tri, i, j, dp):
n = len (tri) ;
for j in range ( 0 ,n):
dp[n - 1 ][j] = tri[n - 1 ][j] ;
for i in range (n - 2 , - 1 , - 1 ):
for j in range (i, - 1 , - 1 ):
dp[i][j] = tri[i][j] + max (dp[i + 1 ][j] , dp[i + 1 ][j + 1 ]) ;
return dp[ 0 ][ 0 ] ;
def maxSumPath(tri):
n = len (tri) ;
dp = [[ - 1 ] * n for _ in range (n)];
return helper(tri, 0 , 0 , dp) ;
tri = [[ 1 ],[ 2 , 1 ],[ 3 , 3 , 2 ]];
print (maxSumPath(tri));
|
C#
using System;
public class GFG {
static int helper( int [][] tri, int i, int j, int [, ] dp)
{
int n = tri.GetLength(0);
for (j = 0; j < n; j++) {
dp[n - 1, j] = tri[n - 1][j];
}
for (i = n - 2; i >= 0; i--) {
for (j = i; j >= 0; j--) {
dp[i, j] = tri[i][j]
+ Math.Max(dp[i + 1, j],
dp[i + 1, j + 1]);
}
}
return dp[0, 0];
}
static int maxSumPath( int [][] tri)
{
int n = tri.GetLength(0);
int [, ] dp = new int [n, n];
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
dp[i, j] = -1;
}
}
return helper(tri, 0, 0, dp);
}
static public void Main()
{
int [][] tri = new int [3][];
tri[0] = new int [] { 1 };
tri[1] = new int [] { 2, 1 };
tri[2] = new int [] { 3, 3, 2 };
Console.WriteLine(maxSumPath(tri));
}
}
|
Javascript
function helper(tri, i, j, dp){
let n = tri.length;
for (j = 0; j < n; j++) {
dp[n - 1][j] = tri[n - 1][j];
}
for (i = n - 2; i >= 0; i--) {
for (j = i; j >= 0; j--) {
dp[i][j] = tri[i][j]
+ Math.max(dp[i + 1][j],
dp[i + 1][j + 1]);
}
}
return dp[0][0];
}
function maxSumPath(tri){
let n = tri.length;
let dp = new Array();
for (let i=0;i<n;i++){
dp[i] = new Array();
for (let j=0;j<n;j++){
dp[i][j] = -1;
}
}
return helper(tri, 0, 0, dp);
}
let tri = [ [1], [2, 1], [3, 3, 2] ];
console.log(maxSumPath(tri));
|
Complexity Analysis:
- Time Complexity: O(m*n) where m = no of rows and n = no of columns
- Auxiliary Space: O(n2)
Method 4: Space Optimization(Without changing the input matrix)
We don’t need a matrix of m*n size. It will store all the results.
We just need the triangle row minimum of the immediate bottom row
So using this approach we can optimize the space from O(m*n) to O(n).
The approach remains the same as that of Method 3.
C++
#include <bits/stdc++.h>
using namespace std;
int helper(vector<vector< int >>& tri, int i, int j, vector<vector< int >>& dp){
int n = tri.size() ;
vector< int > front(n, -1) , curr(n, -1) ;
for ( int j = 0; j < n; j++ ){
front[j] = tri[n-1][j] ;
}
for ( int i = n-2; i >= 0; i--){
for ( int j = i; j >= 0; j-- ){
curr[j] = tri[i][j] + max(front[j] , front[j+1]) ;
}
front = curr ;
}
return front[0] ;
}
int maxSumPath(vector<vector< int >>& tri) {
int n = tri.size() ;
vector<vector< int >> dp(n, vector< int >(n, -1) ) ;
return helper(tri, 0, 0, dp) ;
}
int main()
{
vector<vector< int > > tri{ { 1 },
{ 2, 1 },
{ 3, 3, 2 } };
cout << maxSumPath(tri);
return 0;
}
|
Java
import java.util.*;
class GFG {
static int helper( int [][] tri, int i, int j, int [][] dp){
int n = tri.length;
int [] front= new int [n];
int [] curr= new int [n];
for ( int t= 0 ;t<n;t++)
{
front[t]=- 1 ;
curr[t]=- 1 ;
}
for (j = 0 ; j < n; j++ ){
front[j] = tri[n- 1 ][j] ;
}
for (i = n- 2 ; i >= 0 ; i--){
for (j = i; j >= 0 ; j-- ){
curr[j] = tri[i][j] + Math.max(front[j] , front[j+ 1 ]) ;
}
front = curr ;
}
return front[ 0 ] ;
}
static int maxSumPath( int [][] tri) {
int n = tri.length;
int [][] dp = new int [n][n];
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < n; j++) {
dp[i][j] = - 1 ;
}
}
return helper(tri, 0 , 0 , dp) ;
}
public static void main(String[] args)
{
int [][] tri = { { 1 }, { 2 , 1 }, { 3 , 3 , 2 } };
System.out.println(maxSumPath(tri));
}
}
|
Python3
def helper(tri, i, j, dp):
n = len (tri)
front = [ - 1 ] * n
curr = [ - 1 ] * n
for j in range (n):
front[j] = tri[n - 1 ][j]
for i in range (n - 2 , - 1 , - 1 ):
for j in range (i, - 1 , - 1 ):
curr[j] = tri[i][j] + max (front[j], front[j + 1 ])
front = curr
return front[ 0 ]
def maxSumPath(tri):
n = len (tri)
dp = [[ - 1 ] * n for _ in range (n)]
return helper(tri, 0 , 0 , dp)
tri = [ [ 1 ],
[ 2 , 1 ],
[ 3 , 3 , 2 ] ]
print (maxSumPath(tri))
|
C#
using System;
class GFG
{
public static int helper( int [][] tri, int i, int j,
int [][] dp)
{
int n = tri.Length;
int [] front = new int [n];
int [] curr = new int [n];
for ( int t = 0; t < n; t++) {
front[t] = -1;
curr[t] = -1;
}
for (j = 0; j < n; j++) {
front[j] = tri[n - 1][j];
}
for (i = n - 2; i >= 0; i--) {
for (j = i; j >= 0; j--) {
curr[j]
= tri[i][j]
+ Math.Max(front[j], front[j + 1]);
}
front = curr;
}
return front[0];
}
public static int maxSumPath( int [][] tri)
{
int n = tri.Length;
int [][] dp = new int [n][];
for ( int i = 0; i < n; i++) {
dp[i] = new int [n];
for ( int j = 0; j < n; j++) {
dp[i][j] = -1;
}
}
return helper(tri, 0, 0, dp);
}
public static void Main( string [] args)
{
int [][] tri = { new [] { 1 }, new [] { 2, 1 },
new [] { 3, 3, 2 } };
Console.WriteLine(maxSumPath(tri));
}
}
|
Javascript
function helper(tri, i, j, dp){
let n = tri.length ;
let front= new Array(n, -1) , curr= new Array(n, -1) ;
for (let j = 0; j < n; j++ ){
front[j] = tri[n-1][j] ;
}
for (let i = n-2; i >= 0; i--){
for (let j = i; j >= 0; j-- ){
curr[j] = tri[i][j] + Math.max(front[j] , front[j+1]) ;
}
front = curr ;
}
return front[0] ;
}
function maxSumPath(tri) {
let n = tri.length ;
let dp= new Array(n);
for (let i=0; i<n; i++)
dp[i]= new Array(n).fill(-1);
return helper(tri, 0, 0, dp) ;
}
let tri=[[ 1 ],[ 2, 1 ],[ 3, 3, 2 ]];
console.log(maxSumPath(tri));
|
Complexity Analysis:
- Time Complexity: O(m*n) where m = no of rows and n = no of columns
- Space Complexity: O(n)
Method 5: Space Optimization (Changing the input matrix)
C++
#include<bits/stdc++.h>
using namespace std;
int maxSum( int tri[][3], int n)
{
if (n > 1)
tri[1][1] = tri[1][1] + tri[0][0];
tri[1][0] = tri[1][0] + tri[0][0];
for ( int i = 2; i < n; i++) {
tri[i][0] = tri[i][0] + tri[i-1][0];
tri[i][i] = tri[i][i] + tri[i-1][i-1];
for ( int j = 1; j < i; j++){
if (tri[i][j] + tri[i-1][j-1] >=
tri[i][j] + tri[i-1][j])
tri[i][j] = tri[i][j] + tri[i-1][j-1];
else
tri[i][j] = tri[i][j]+tri[i-1][j];
}
}
int max=tri[n-1][0];
for ( int i=1;i<n;i++)
{
if (max<tri[n-1][i])
max=tri[n-1][i];
}
return max;
}
int main(){
int tri[3][3] = {{1}, {2,1}, {3,3,2}};
cout<<maxSum(tri, 3);
return 0;
}
|
Java
import java.io.*;
class GFG
{
static int maxSum( int tri[][], int n)
{
if (n > 1 )
tri[ 1 ][ 1 ] = tri[ 1 ][ 1 ] + tri[ 0 ][ 0 ];
tri[ 1 ][ 0 ] = tri[ 1 ][ 0 ] + tri[ 0 ][ 0 ];
for ( int i = 2 ; i < n; i++) {
tri[i][ 0 ] = tri[i][ 0 ] + tri[i- 1 ][ 0 ];
tri[i][i] = tri[i][i] + tri[i- 1 ][i- 1 ];
for ( int j = 1 ; j < i; j++){
if (tri[i][j] + tri[i- 1 ][j- 1 ] >=
tri[i][j] + tri[i- 1 ][j])
tri[i][j] = tri[i][j]
+ tri[i- 1 ][j- 1 ];
else
tri[i][j] = tri[i][j]
+ tri[i- 1 ][j];
}
}
int max = tri[n- 1 ][ 0 ];
for ( int i = 1 ; i < n; i++)
{
if (max < tri[n- 1 ][i])
max = tri[n- 1 ][i];
}
return max;
}
public static void main (String[] args)
{
int tri[][] = {{ 1 }, { 2 , 1 }, { 3 , 3 , 2 }};
System.out.println(maxSum(tri, 3 ));
}
}
|
Python3
def maxSum(tri, n):
if n > 1 :
tri[ 1 ][ 1 ] = tri[ 1 ][ 1 ] + tri[ 0 ][ 0 ]
tri[ 1 ][ 0 ] = tri[ 1 ][ 0 ] + tri[ 0 ][ 0 ]
for i in range ( 2 , n):
tri[i][ 0 ] = tri[i][ 0 ] + tri[i - 1 ][ 0 ]
tri[i][i] = tri[i][i] + tri[i - 1 ][i - 1 ]
for j in range ( 1 , i):
if tri[i][j] + tri[i - 1 ][j - 1 ] > = tri[i][j] + tri[i - 1 ][j]:
tri[i][j] = tri[i][j] + tri[i - 1 ][j - 1 ]
else :
tri[i][j] = tri[i][j] + tri[i - 1 ][j]
print ( max (tri[n - 1 ]))
tri = [[ 1 ], [ 2 , 1 ], [ 3 , 3 , 2 ]]
maxSum(tri, 3 )
|
C#
using System;
class GFG
{
static int maxSum( int [,]tri,
int n)
{
if (n > 1)
tri[1, 1] = tri[1, 1] +
tri[0, 0];
tri[1, 0] = tri[1, 0] +
tri[0, 0];
for ( int i = 2; i < n; i++)
{
tri[i, 0] = tri[i, 0] +
tri[i - 1, 0];
tri[i, i] = tri[i, i] +
tri[i - 1, i - 1];
for ( int j = 1; j < i; j++)
{
if (tri[i, j] + tri[i - 1, j - 1] >=
tri[i, j] + tri[i - 1, j])
tri[i, j] = tri[i, j] +
tri[i - 1, j - 1];
else
tri[i, j] = tri[i, j] +
tri[i - 1, j];
}
}
int max = tri[n - 1, 0];
for ( int i = 1; i < n; i++)
{
if (max < tri[n - 1, i])
max = tri[n - 1, i];
}
return max;
}
public static void Main ()
{
int [,]tri = {{1,0,0},
{2,1,0},
{3,3,2}};
Console.Write(maxSum(tri, 3));
}
}
|
PHP
<?php
function maxSum( $tri , $n )
{
if ( $n > 1)
$tri [1][1] = $tri [1][1] + $tri [0][0];
$tri [1][0] = $tri [1][0] + $tri [0][0];
for ( $i = 2; $i < $n ; $i ++)
{
$tri [ $i ][0] = $tri [ $i ][0] +
$tri [ $i - 1][0];
$tri [ $i ][ $i ] = $tri [ $i ][ $i ] +
$tri [ $i - 1][ $i - 1];
for ( $j = 1; $j < $i ; $j ++)
{
if ( $tri [ $i ][ $j ] + $tri [ $i - 1][ $j - 1] >=
$tri [ $i ][ $j ] + $tri [ $i - 1][ $j ])
$tri [ $i ][ $j ] = $tri [ $i ][ $j ] +
$tri [ $i - 1][ $j - 1];
else
$tri [ $i ][ $j ] = $tri [ $i ][ $j ] +
$tri [ $i - 1][ $j ];
}
}
$max = $tri [ $n - 1][0];
for ( $i = 1; $i < $n ; $i ++)
{
if ( $max < $tri [ $n - 1][ $i ])
$max = $tri [ $n - 1][ $i ];
}
return $max ;
}
$tri = array ( array (1),
array (2,1),
array (3,3,2));
echo maxSum( $tri , 3);
?>
|
Javascript
<script>
function maxSum(tri, n)
{
if (n > 1)
tri[1][1] = tri[1][1] + tri[0][0];
tri[1][0] = tri[1][0] + tri[0][0];
for (let i = 2; i < n; i++) {
tri[i][0] = tri[i][0] + tri[i-1][0];
tri[i][i] = tri[i][i] + tri[i-1][i-1];
for (let j = 1; j < i; j++){
if (tri[i][j] + tri[i-1][j-1] >=
tri[i][j] + tri[i-1][j])
tri[i][j] = tri[i][j]
+ tri[i-1][j-1];
else
tri[i][j] = tri[i][j]
+ tri[i-1][j];
}
}
let max = tri[n-1][0];
for (let i = 1; i < n; i++)
{
if (max < tri[n-1][i])
max = tri[n-1][i];
}
return max;
}
let tri = [[1], [2,1], [3,3,2]];
document.write(maxSum(tri, 3));
</script>
|
Complexity Analysis:
- Time Complexity: O(m*n) where m = no of rows and n = no of columns
- Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...