Given a triangular structure of numbers, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
Examples :
Input :
2
3 7
8 5 6
6 1 9 3
Output : 11
Explanation : 2 + 3 + 5 + 1 = 11
Input :
3
6 4
5 2 7
9 1 8 6
Output : 10
Explanation : 3 + 4 + 2 + 1 = 10
Naive Approach : 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;
int helper(vector<vector< int >>& A, int i, int j){
if (i == A.size() ){
return 0 ;
}
int mn ;
mn = A[i][j] + min(helper(A, i+1,j), helper(A,i+1, j+1)) ;
return mn ;
}
int minSumPath(vector<vector< int >>& A) {
return helper(A, 0, 0) ;
}
int main()
{
vector<vector< int > > A{ { 2 },
{ 3, 9 },
{ 1, 6, 7 } };
cout << minSumPath(A);
return 0;
}
|
Java
import java.io.*;
class GFG {
static int helper( int A[][], int i, int j)
{
if (i == A.length){
return 0 ;
}
int mn ;
mn = A[i][j] + Math.min(helper(A, i+ 1 ,j), helper(A,i+ 1 , j+ 1 )) ;
return mn ;
}
static int minSumPath( int A[][]) {
return helper(A, 0 , 0 ) ;
}
public static void main(String[] args)
{
int triangle [][] = { { 2 },
{ 3 , 9 },
{ 1 , 6 , 7 } };
System.out.print(minSumPath(triangle));
}
}
|
Python3
def helper(A, i, j):
if (i = = len (A)):
return 0
mn = A[i][j] + min (helper(A, i + 1 , j), helper(A, i + 1 , j + 1 ))
return mn
def minSumPath(A):
return helper(A, 0 , 0 )
A = [ [ 2 ], [ 3 , 9 ], [ 1 , 6 , 7 ] ]
print (minSumPath(A))
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
static int helper( ref List<List< int >> A, int i, int j)
{
if (i == A.Count ) {
return 0 ;
}
int mn ;
mn = A[i][j] + Math.Min(helper( ref A, i + 1, j),
helper( ref A, i + 1, j + 1)) ;
return mn ;
}
static int minSumPath( ref List<List< int >> A) {
return helper( ref A, 0, 0) ;
}
public static void Main() {
List<List< int >> A = new List<List< int >>();
A.Add( new List< int > {2});
A.Add( new List< int > {3, 9});
A.Add( new List< int > {1, 6, 7});
Console.WriteLine(minSumPath( ref A));
}
}
|
Javascript
<script>
function helper(A, i, j)
{
if (i == A.length )
{
return 0 ;
}
let mn ;
mn = A[i][j] + Math.min(helper(A, i + 1,j), helper(A, i + 1, j + 1)) ;
return mn ;
}
function minSumPath(A)
{
return helper(A, 0, 0) ;
}
let A = [ [ 2 ], [ 3, 9 ], [ 1, 6, 7 ] ];
document.write(minSumPath(A));
</script>
|
Time Complexity: O(2N*N) where N = number of rows and M = number of columns
Auxiliary Space: O(N)
There are two ways to reach the solution :
1. Memoization – Starting from the top node, traverse recursively with each node, till the pathsum of that node is calculated. And then store the result in an array. But this will take O(N^2) space to maintain the array.
Implementation of Above Approach:
C++
#include <bits/stdc++.h>
using namespace std;
int helper(vector<vector< int >>& A, int i, int j, vector<vector< int >>& dp){
if (i == A.size() ){
return 0 ;
}
if (dp[i][j] != -1){
return dp[i][j] ;
}
return dp[i][j] = A[i][j] + min(helper(A, i+1,j, dp), helper(A,i+1, j+1, dp)) ;
}
int minSumPath(vector<vector< int >>& A) {
int n = A.size() ;
vector<vector< int >> dp(n, vector< int >(n, -1) ) ;
return helper(A, 0, 0, dp) ;
}
int main()
{
vector<vector< int > > A{ { 2 },
{ 3, 9 },
{ 1, 6, 7 } };
cout << minSumPath(A);
return 0;
}
|
Java
import java.io.*;
import java.util.Arrays;
class GFG {
public static int helper( int A[][], int i, int j, int dp[][])
{
if (i == A.length) {
return 0 ;
}
if (dp[i][j] != - 1 ) return dp[i][j];
return dp[i][j] = A[i][j] + Math.min(helper(A, i+ 1 , j, dp), helper(A, i+ 1 , j + 1 , dp));
}
public static int minSumPath( int A[][]) {
int n = A.length;
int dp[][] = new int [n][n];
for ( int [] row : dp)
Arrays.fill(row,- 1 );
return helper(A, 0 , 0 , dp) ;
}
public static void main(String[] args)
{
int A [][] = { { 2 },
{ 3 , 9 },
{ 1 , 6 , 7 } };
System.out.print(minSumPath(A));
}
}
|
Python3
def helper(A, i, j, dp):
if (i = = len (A)):
return 0
if (dp[i][j] ! = - 1 ):
return dp[i][j]
dp[i][j] = A[i][j] + min (helper(A, i + 1 ,j, dp), helper(A,i + 1 , j + 1 , dp))
return dp[i][j]
def minSumPath(A):
n = len (A)
dp = [[ - 1 ] * n] * n
return helper(A, 0 , 0 , dp)
A = [ [ 2 ],[ 3 , 9 ],[ 1 , 6 , 7 ] ]
print (minSumPath(A))
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
static int helper( ref List<List< int >> A, int i, int j, int [,] dp)
{
if (i == A.Count) {
return 0;
}
if (dp[i, j] != -1) return dp[i, j];
return dp[i, j] = A[i][j] + Math.Min(helper( ref A, i + 1, j, dp), helper( ref A, i + 1, j + 1, dp));
}
static int minSumPath( ref List<List< int >> A) {
int n = A.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;
}
}
return helper( ref A, 0, 0, dp) ;
}
public static void Main() {
List<List< int >> A = new List<List< int >>();
A.Add( new List< int > {2});
A.Add( new List< int > {3, 9});
A.Add( new List< int > {1, 6, 7});
Console.WriteLine(minSumPath( ref A));
}
}
|
Javascript
<script>
function helper(A, i, j, dp)
{
if (i == A.length){
return 0 ;
}
if (dp[i][j] != -1)
{
return dp[i][j] ;
}
return dp[i][j] = A[i][j] + Math.min(helper(A, i+1,j, dp), helper(A,i+1, j+1, dp)) ;
}
function minSumPath(A) {
let n = A.length ;
let dp = new Array(n);
for (let i=0;i<n;i++){
dp[i] = new Array(n).fill(-1);
}
return helper(A, 0, 0, dp) ;
}
let A = [ [ 2 ],[ 3, 9 ],[ 1, 6, 7 ] ];
document.write(minSumPath(A));
</script>
|
Time Complexity: O(N*M) where N = number of rows and M = number of columns
Auxiliary Space: O(N2)
2. Bottom up – Start from the nodes on the bottom row; the min pathsum for these nodes are the values of the nodes themselves. And after that, minimum pathsum at the ith node of kth row would be the minimum of the pathsum of its two children + the node’s value, i.e.:
memo[k][i] = min( memo[k+1][i], memo[k+1][i+1]) + A[k][i];
OR
Simply set memo as a 1D array, and update it
this will be space efficient also :
For the row k :
memo[i] = min( memo[i], memo[i+1]) + A[k][i];
Below is the implementation of above dynamic programming approach :
C++
#include <bits/stdc++.h>
using namespace std;
int minSumPath(vector<vector< int > >& A)
{
int memo[A.size()];
int n = A.size() - 1;
for ( int i = 0; i < A[n].size(); i++)
memo[i] = A[n][i];
for ( int i = A.size() - 2; i >= 0; i--)
for ( int j = 0; j < A[i].size(); j++)
memo[j] = A[i][j] + min(memo[j],
memo[j + 1]);
return memo[0];
}
int main()
{
vector<vector< int > > A{ { 2 },
{ 3, 9 },
{ 1, 6, 7 } };
cout << minSumPath(A);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
static int A[][] = {{ 2 },
{ 3 , 9 },
{ 1 , 6 , 7 }};
static int minSumPath()
{
int []memo = new int [A.length];
int n = A.length - 1 ;
for ( int i = 0 ;
i < A[n].length; i++)
memo[i] = A[n][i];
for ( int i = A.length - 2 ;
i >= 0 ; i--)
for ( int j = 0 ;
j < A[i].length; j++)
memo[j] = A[i][j] +
( int )Math.min(memo[j],
memo[j + 1 ]);
return memo[ 0 ];
}
public static void main(String args[])
{
System.out.print(minSumPath());
}
}
|
Python3
def minSumPath(A):
memo = [ None ] * len (A)
n = len (A) - 1
for i in range ( len (A[n])):
memo[i] = A[n][i]
for i in range ( len (A) - 2 , - 1 , - 1 ):
for j in range ( len (A[i])):
memo[j] = A[i][j] + min (memo[j],
memo[j + 1 ]);
return memo[ 0 ]
A = [[ 2 ],
[ 3 , 9 ],
[ 1 , 6 , 7 ]]
print (minSumPath(A))
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
static int minSumPath( ref List<List< int >> A)
{
int []memo = new int [A.Count];
int n = A.Count - 1;
for ( int i = 0; i < A[n].Count; i++)
memo[i] = A[n][i];
for ( int i = A.Count - 2; i >= 0; i--)
for ( int j = 0; j < A[i + 1].Count - 1; j++)
memo[j] = A[i][j] +
( int )Math.Min(memo[j],
memo[j + 1]);
return memo[0];
}
public static void Main()
{
List<List< int >> A = new List<List< int >>();
A.Add( new List< int > {2});
A.Add( new List< int > {3, 9});
A.Add( new List< int > {1, 6, 7});
Console.WriteLine(minSumPath( ref A));
}
}
|
PHP
<?php
function minSumPath(& $A )
{
$memo = array ();
for ( $i = 0; $i < count ( $A ); $i ++)
$memo [ $i ] = 0;
$n = count ( $A ) - 1;
for ( $i = 0;
$i < count ( $A [ $n ]); $i ++)
$memo [ $i ] = $A [ $n ][ $i ];
for ( $i = count ( $A ) - 2; $i >= 0; $i --)
for ( $j = 0;
$j < count ( $A [ $i + 1]) - 1; $j ++)
$memo [ $j ] = $A [ $i ][ $j ] +
min( $memo [ $j ],
$memo [ $j + 1]);
return $memo [0];
}
$A = array ( array (2),
array (3, 9),
array (1, 6, 7));
echo (minSumPath( $A ));
?>
|
Javascript
<script>
let A = [[2], [3, 9], [1, 6, 7]];
function minSumPath()
{
let memo = [];
let n = A.length - 1;
for (let i = 0; i < A[n].length; i++)
memo[i] = A[n][i];
for (let i = A.length - 2; i >= 0; i--)
for (let j = 0;
j < A[i].length; j++)
memo[j] = A[i][j] +
Math.min(memo[j],
memo[j + 1]);
return memo[0];
}
document.write(minSumPath());
</script>
|
Time Complexity: O(N*M) where N = number of rows and M = number of columns
Auxiliary Space: O(N)
Space Optimization Approach: Instead of using another array we can store results in the same array.
C++
#include <bits/stdc++.h>
using namespace std;
int minSumPath(vector<vector< int > >& A)
{
int n = A.size();
int ans = 0;
for ( int i = 0; i < n; i++) {
int minimum = INT_MAX;
for ( int j = 0; j <= i; j++) {
if (i == 0 && j == 0) {
minimum = min(minimum, A[i][j]);
continue ;
}
if (j == i) {
A[i][j] = A[i][j] + A[i - 1][j - 1];
minimum = min(minimum, A[i][j]);
continue ;
}
int up = A[i][j], down = A[i][j];
if (j > 0) {
up += A[i - 1][j - 1];
}
else {
up = INT_MAX;
}
down += A[i - 1][j];
A[i][j] = min(up, down);
minimum = min(minimum, A[i][j]);
}
ans = minimum;
}
return ans;
}
int main()
{
vector<vector< int > > A{ { 2 }, { 3, 9 }, { 1, 6, 7 } };
cout << minSumPath(A);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static int A[][] = { { 2 }, { 3 , 9 }, { 1 , 6 , 7 } };
static int minSumPath()
{
int n = A.length;
int ans = 0 ;
for ( int i = 0 ; i < n; i++) {
int minimum = Integer.MAX_VALUE;
for ( int j = 0 ; j <= i; j++) {
if (i == 0 && j == 0 ) {
minimum = Math.min(minimum, A[i][j]);
continue ;
}
if (j == i) {
A[i][j] = A[i][j] + A[i - 1 ][j - 1 ];
minimum = Math.min(minimum, A[i][j]);
continue ;
}
int up = A[i][j], down = A[i][j];
if (j > 0 ) {
up += A[i - 1 ][j - 1 ];
}
else {
up = Integer.MAX_VALUE;
}
down += A[i - 1 ][j];
A[i][j] = Math.min(up, down);
minimum = Math.min(minimum, A[i][j]);
}
ans = minimum;
}
return ans;
}
public static void main(String args[])
{
System.out.print(minSumPath());
}
}
|
Python3
def minSumPath(A):
n = len (A)
ans = 0
for i in range (n):
minimum = float ( "inf" )
for j in range (i + 1 ):
if i = = 0 and j = = 0 :
minimum = min (minimum, A[i][j])
continue
if j = = i:
A[i][j] = A[i][j] + A[i - 1 ][j - 1 ]
minimum = min (minimum, A[i][j])
continue
up = A[i][j]
down = A[i][j]
if j > 0 :
up + = A[i - 1 ][j - 1 ]
else :
up = float ( "inf" )
down + = A[i - 1 ][j]
A[i][j] = min (up, down)
minimum = min (minimum, A[i][j])
ans = minimum
return ans
A = [[ 2 ], [ 3 , 9 ], [ 1 , 6 , 7 ]]
print (minSumPath(A))
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class HelloWorld
{
static List<List< int >> A = new List<List< int >>();
public static int minSumPath()
{
int n = A.Count;
int ans = 0;
for ( int i = 0; i < n; i++) {
int minimum = Int32.MaxValue;
for ( int j = 0; j <= i; j++)
{
if (i == 0 && j == 0)
{
minimum = Math.Min(minimum, A[i][j]);
continue ;
}
if (j == i) {
A[i][j] = A[i][j] + A[i - 1][j - 1];
minimum = Math.Min(minimum, A[i][j]);
continue ;
}
int up = A[i][j], down = A[i][j];
if (j > 0) {
up += A[i - 1][j - 1];
}
else {
up = Int32.MaxValue;
}
down += A[i - 1][j];
A[i][j] = Math.Min(up, down);
minimum = Math.Min(minimum, A[i][j]);
}
ans = minimum;
}
return ans;
}
public static void Main( string [] args)
{
A.Add( new List< int > {2});
A.Add( new List< int > {3, 9});
A.Add( new List< int > {1, 6, 7});
Console.Write(minSumPath());
}
}
|
Javascript
<script>
function minSumPath(A)
{
let n = A.length;
let ans = 0;
for (let i = 0; i < n; i++) {
let minimum = Number.MAX_SAFE_INTEGER;
for (let j = 0; j <= i; j++) {
if (i == 0 && j == 0) {
minimum = Math.min(minimum, A[i][j]);
continue ;
}
if (j == i) {
A[i][j] = A[i][j] + A[i - 1][j - 1];
minimum = Math.min(minimum, A[i][j]);
continue ;
}
let up = A[i][j], down = A[i][j];
if (j > 0) {
up += A[i - 1][j - 1];
}
else {
up = Number.MAX_SAFE_INTEGER;
}
down += A[i - 1][j];
A[i][j] = Math.min(up, down);
minimum = Math.min(minimum, A[i][j]);
}
ans = minimum;
}
return ans;
}
let A=[ [ 2 ], [ 3, 9 ], [ 1, 6, 7] ];
document.write(minSumPath(A));
</script>
|
Output:
6
Time Complexity: O(N*M) where N = number of rows and M = number of columns
Auxiliary Space: O(1)
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 :
12 Jan, 2023
Like Article
Save Article