Minimum Sum Path in a Triangle
Last Updated :
06 Nov, 2024
Given a triangular array, find the minimum path sum from top to bottom. For each step, we can move to the adjacent numbers of the row below. i.e., if we are on an index i of the current row, we can move to either index i or index i + 1 on the next row.
Examples :
Input: triangle[][] = [[2],
[3, 7],
[8, 5, 6],
[6, 1, 9, 3]]
Output: 11
Explanation : The path is 2 → 3 → 5 → 1, which results in a minimum sum of 2 + 3 + 5 + 1 = 11.
Input: triangle[][] = [[3],
[6, 9],
[8, 7, 1],
[9, 6, 8, 2]]
Output: 15
Explanation: The path is 3 → 9 → 1 → 2, which results in a minimum sum of 3 + 9 + 1 + 2 = 15.
Using Recursion – O(2 ^ (n*n)) Time and O(n) Space
This problem follows the recursive property. At each position in the triangle, the minimum path sum will depend on the minimum path sums of adjacent positions in the row below. Thus, for any position (i, j) in the triangle, we can find the minimum path sum using the minimum path sums of (i+1, j) and (i+1, j+1) positions. This gives us the following recurrence relation:
minPathSum(i, j) = triangle[i][j] + min(minPathSum(i+1, j), minPathSum(i+1 ,j+1))
C++
// C++ program to find Minimum Sum Path in a Triangle using
// Recursion
#include <iostream>
#include <vector>
using namespace std;
int minSumPathRec(vector<vector<int>>& triangle, int i, int j) {
// Base Case: If we go below the last row return zero.
if(i == triangle.size())
return 0 ;
// Find the current min path sum by recursively calculating
// the minimum path sum of the next row's adjacent elements
return triangle[i][j] + min(minSumPathRec(triangle, i+1,j),
minSumPathRec(triangle,i+1, j+1));
}
int minSumPath(vector<vector<int>> &triangle) {
return minSumPathRec(triangle,0, 0);
}
int main() {
vector<vector<int> > triangle{{2},
{3, 9},
{1, 6, 7}};
cout << minSumPath(triangle);
return 0;
}
Java
// Java program to Find Minimum Sum Path in
// a Triangle using Recursion
import java.util.ArrayList;
import java.util.List;
class GfG {
static int
minSumPathRec(ArrayList<ArrayList<Integer> > triangle,
int i, int j) {
// Base Case: If we go below the last row return
// zero.
if (i == triangle.size())
return 0;
// Find the current min path sum by recursively
// calculating the minimum path sum of the next
// row's adjacent elements
return triangle.get(i).get(j)
+ Math.min(
minSumPathRec(triangle, i + 1, j),
minSumPathRec(triangle, i + 1, j + 1));
}
static int
minSumPath(ArrayList<ArrayList<Integer> > triangle) {
return minSumPathRec(triangle, 0, 0);
}
public static void main(String[] args) {
ArrayList<ArrayList<Integer> > triangle
= new ArrayList<>();
triangle.add(new ArrayList<>(List.of(2)));
triangle.add(new ArrayList<>(List.of(3, 9)));
triangle.add(new ArrayList<>(List.of(1, 6, 7)));
System.out.println(minSumPath(triangle));
}
}
Python
# Python program to find Minimum Sum Path in
# a Triangle using Recursion
def minSumPathRec(triangle, i, j):
# Base Case: If we go below the last row return zero.
if i == len(triangle):
return 0
# Find the current min path sum by recursively calculating
# the minimum path sum of the next row's adjacent elements
return triangle[i][j] + min(minSumPathRec(triangle, i + 1, j),
minSumPathRec(triangle, i + 1, j + 1))
def minSumPath(triangle):
return minSumPathRec(triangle, 0, 0)
triangle = [
[2],
[3, 9],
[1, 6, 7]
]
print(minSumPath(triangle))
C#
// C# program to find Minimum Sum Path in
// a Triangle using Recursion
using System;
using System.Collections.Generic;
class GfG {
static int minSumPathRec(List<List<int> > triangle,
int i, int j) {
// Base Case: If we go below the last row return
// zero.
if (i == triangle.Count)
return 0;
// Find the current min path sum by recursively
// calculating the minimum path sum of the next
// row's adjacent elements
return triangle[i][j]
+ Math.Min(
minSumPathRec(triangle, i + 1, j),
minSumPathRec(triangle, i + 1, j + 1));
}
static int minSumPath(List<List<int> > triangle) {
return minSumPathRec(triangle, 0, 0);
}
static void Main() {
List<List<int> > triangle = new List<List<int> >{
new List<int>{ 2 }, new List<int>{ 3, 9 },
new List<int>{ 1, 6, 7 }
};
Console.WriteLine(minSumPath(triangle));
}
}
JavaScript
// JavaScript program to find Minimum Sum Path in a Triangle
// using Recursion
function minSumPathRec(triangle, i, j) {
// Base Case: If we go below the last row return zero.
if (i === triangle.length)
return 0;
// Find the current min path sum by recursively
// calculating the minimum path sum of the next row's
// adjacent elements
return triangle[i][j]
+ Math.min(
minSumPathRec(triangle, i + 1, j),
minSumPathRec(triangle, i + 1, j + 1));
}
function minSumPath(triangle) {
return minSumPathRec(triangle, 0, 0);
}
const triangle = [ [ 2 ], [ 3, 9 ], [ 1, 6, 7 ] ];
console.log(minSumPath(triangle));
Using Memoization – O(n*n) Time and O(n*n) Space
If we notice carefully, we can observe that this recursive solution holds the following two properties of Dynamic Programming:
1. Optimal Substructure: The minPathSum(i, j), depends on the optimal solution of subproblem minPathSum(i + 1, j) and minPathSum(i + 1, j + 1). By combining these optimal substructures, we can efficiently calculate the minimum path sum of the position (i, j).
2. Overlapping Subproblems: We can see that we are computing the same subproblems multiple times, minPathSum(i + 1, j + 1) will be computed in minPathSum(i, j) as well as minPathSum(i, j + 1). This redundancy leads to overlapping subproblems.
- There are two parameters(i and j) that change in the recursive solution and then can go from 0 to n. So we create a 2D array of size n x n for memoization.
- We initialize this array as -1 to indicate nothing is computed initially.
- Now we modify our recursive solution to first check if the value is -1, then only make recursive calls. This way, we avoid re-computations of the same subproblems.
C++
// C++ program to Find Minimum Sum Path in
// a Triangle using Memoization
#include <iostream>
#include <vector>
using namespace std;
int minSumPathRec(vector<vector<int>> &triangle, int i,
int j, vector<vector<int>> &memo) {
// Base Case
if (i == triangle.size())
return 0;
// if the result for this subproblem is
// already computed then return it
if (memo[i][j] != -1)
return memo[i][j];
// Recurisve Case
return memo[i][j] = triangle[i][j] +
min(minSumPathRec(triangle, i + 1, j, memo),
minSumPathRec(triangle, i + 1, j + 1, memo));
}
int minSumPath(vector<vector<int>> &triangle) {
int n = triangle.size();
// Memo array to store the result
vector<vector<int>> memo(n, vector<int>(n, -1));
return minSumPathRec(triangle, 0, 0, memo);
}
int main() {
vector<vector<int>> triangle{{2}, {3, 9}, {1, 6, 7}};
cout << minSumPath(triangle);
return 0;
}
Java
// Java program to Find Minimum Sum Path in a Triangle using
// Memoization
import java.util.ArrayList;
import java.util.List;
class GfG {
static int
minSumPathRec(ArrayList<ArrayList<Integer> > triangle,
int i, int j, int[][] memo) {
// Base Case
if (i == triangle.size())
return 0;
// If the result for this subproblem is
// already computed then return it
if (memo[i][j] != -1)
return memo[i][j];
// Recursive Case
return memo[i][j]
= triangle.get(i).get(j)
+ Math.min(
minSumPathRec(triangle, i + 1, j, memo),
minSumPathRec(triangle, i + 1, j + 1,
memo));
}
static int
minSumPath(ArrayList<ArrayList<Integer> > triangle) {
int n = triangle.size();
// Memo array to store the result
int[][] memo = new int[n][n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
memo[i][j] = -1;
return minSumPathRec(triangle, 0, 0, memo);
}
public static void main(String[] args) {
ArrayList<ArrayList<Integer> > triangle
= new ArrayList<>();
triangle.add(new ArrayList<>(List.of(2)));
triangle.add(new ArrayList<>(List.of(3, 9)));
triangle.add(new ArrayList<>(List.of(1, 6, 7)));
System.out.println(minSumPath(triangle));
}
}
Python
# Python program to Find Minimum Sum Path in
# a Triangle using Memoization
def minSumPathRec(triangle, i, j, memo):
# Base Case
if i == len(triangle):
return 0
# if the result for this subproblem is
# already computed then return it
if memo[i][j] != -1:
return memo[i][j]
# Recursive Case
memo[i][j] = triangle[i][j] + min(minSumPathRec(triangle, i + 1, j, memo),
minSumPathRec(triangle, i + 1, j + 1, memo))
return memo[i][j]
def minSumPath(triangle):
n = len(triangle)
# Memo array to store the result
memo = [[-1] * n for i in range(n)]
return minSumPathRec(triangle, 0, 0, memo)
triangle = [
[2],
[3, 9],
[1, 6, 7]
]
print(minSumPath(triangle))
C#
// C# program to Find Minimum Sum Path in a Triangle using
// Memoization
using System;
using System.Collections.Generic;
class GfG {
static int minSumPathRec(List<List<int> > triangle,
int i, int j, int[][] memo) {
// Base Case
if (i == triangle.Count)
return 0;
// If the result for this subproblem is
// already computed then return it
if (memo[i][j] != -1)
return memo[i][j];
// Recursive Case
memo[i][j]
= triangle[i][j]
+ Math.Min(
minSumPathRec(triangle, i + 1, j, memo),
minSumPathRec(triangle, i + 1, j + 1,
memo));
return memo[i][j];
}
static int minSumPath(List<List<int> > triangle) {
int n = triangle.Count;
// Memo array to store the result
int[][] memo = new int[n][];
for (int i = 0; i < n; i++) {
memo[i] = new int[n];
Array.Fill(memo[i], -1);
}
return minSumPathRec(triangle, 0, 0, memo);
}
static void Main() {
List<List<int> > triangle = new List<List<int> >{
new List<int>{ 2 }, new List<int>{ 3, 9 },
new List<int>{ 1, 6, 7 }
};
Console.WriteLine(minSumPath(triangle));
}
}
JavaScript
// JavaScript program to Find Minimum Sum Path in a Triangle
// using Memoization
function minSumPathRec(triangle, i, j, memo) {
// Base Case
if (i === triangle.length)
return 0;
// if the result for this subproblem is
// already computed then return it
if (memo[i][j] !== -1)
return memo[i][j];
// Recursive Case
memo[i][j]
= triangle[i][j]
+ Math.min(
minSumPathRec(triangle, i + 1, j, memo),
minSumPathRec(triangle, i + 1, j + 1, memo));
return memo[i][j];
}
function minSumPath(triangle) {
const n = triangle.length;
// Memo array to store the result
const memo
= Array.from({length : n}, () => Array(n).fill(-1));
return minSumPathRec(triangle, 0, 0, memo);
}
const triangle = [ [ 2 ], [ 3, 9 ], [ 1, 6, 7 ] ];
console.log(minSumPath(triangle));
Using Tabulation – O(n*n) Time and O(n*n) Space
The approach is similar to the previous one; just instead of breaking down the problem recursively, we iteratively build up the solution by calculating in bottom-up manner. Maintain a dp[][] table such that dp[i][j] stores the minimum path sum to reach position (i, j).
- Base Case: For the last row i.e., i = n - 1, dp[i][j] = triangle[i][j]
- Recursive Case: For i < n-1, dp[i][j] = triangle[i][j] + min(dp[i + 1][j], dp[i+1][j+1)
C++
// Cpp program to Find Minimum Sum Path in a Triangle
// Using Tabulation
#include <iostream>
#include <vector>
using namespace std;
int minSumPath(vector<vector<int> > &triangle) {
int n = triangle.size();
// Dp array to store the result
vector<vector<int>> dp(n, vector<int>(n));
// Base Case: The last row will be the same as matrix
for (int i = 0; i < n; i++)
dp[n-1][i] = triangle[n - 1][i];
// Calculation of the remaining rows,
// in bottom up manner
for (int i = n - 2; i >= 0; i--)
for (int j = 0; j < triangle[i].size(); j++)
dp[i][j] = triangle[i][j] + min(dp[i + 1][j],
dp[i + 1][j + 1]);
return dp[0][0];
}
int main() {
vector<vector<int> > triangle{{2},
{3, 9},
{1, 6, 7}};
cout << minSumPath(triangle);
return 0;
}
Java
// Java program to Find Minimum Sum Path in a Triangle using
// Tabulation
import java.util.ArrayList;
class GfG {
static int
minSumPath(ArrayList<ArrayList<Integer> > triangle) {
int n = triangle.size();
// DP array to store the result
int[][] dp = new int[n][n];
// Base Case: The last row will be the same as
// triangle
for (int i = 0; i < n; i++)
dp[n - 1][i] = triangle.get(n - 1).get(i);
// Calculation of the remaining rows,
// in bottom up manner
for (int i = n - 2; i >= 0; i--)
for (int j = 0; j < triangle.get(i).size(); j++)
dp[i][j] = triangle.get(i).get(j)
+ Math.min(dp[i + 1][j],
dp[i + 1][j + 1]);
return dp[0][0];
}
public static void main(String[] args) {
ArrayList<ArrayList<Integer> > triangle
= new ArrayList<>();
triangle.add(new ArrayList<Integer>() {
{
add(2);
}
});
triangle.add(new ArrayList<Integer>() {
{
add(3);
add(9);
}
});
triangle.add(new ArrayList<Integer>() {
{
add(1);
add(6);
add(7);
}
});
System.out.println(minSumPath(triangle));
}
}
Python
# Python program to Find Minimum Sum Path
# in a Triangle using Tabulation
def min_sum_path(triangle):
n = len(triangle)
# DP array to store the result
dp = [[0] * n for _ in range(n)]
# Base Case: The last row will be the
# same as triangle
for i in range(n):
dp[n - 1][i] = triangle[n - 1][i]
# Calculation of the remaining rows,
# in bottom up manner
for i in range(n - 2, -1, -1):
for j in range(len(triangle[i])):
dp[i][j] = triangle[i][j] + min(dp[i + 1][j],
dp[i + 1][j + 1])
return dp[0][0]
triangle = [[2],
[3, 9],
[1, 6, 7]]
print(min_sum_path(triangle))
C#
// C# program to Find Minimum Sum Path in a Triangle using
// Tabulation
using System;
using System.Collections.Generic;
class GfG {
static int minSumPath(List<List<int> > triangle) {
int n = triangle.Count;
// DP array to store the result
int[][] dp = new int[n][];
for (int i = 0; i < n; i++) {
dp[i] = new int[n];
}
// Base Case: The last row will be the same as
// triangle
for (int i = 0; i < n; i++)
dp[n - 1][i] = triangle[n - 1][i];
// Calculation of the remaining rows,
// in bottom up manner
for (int i = n - 2; i >= 0; i--)
for (int j = 0; j < triangle[i].Count; j++)
dp[i][j] = triangle[i][j]
+ Math.Min(dp[i + 1][j],
dp[i + 1][j + 1]);
return dp[0][0];
}
static void Main() {
List<List<int> > triangle = new List<List<int> >{
new List<int>{ 2 }, new List<int>{ 3, 9 },
new List<int>{ 1, 6, 7 }
};
Console.WriteLine(minSumPath(triangle));
}
}
JavaScript
// JavaScript program to Find Minimum Sum Path in a Triangle
// using Tabulation
function minSumPath(triangle) {
const n = triangle.length;
// DP array to store the result
const dp = Array.from(Array(n), () => new Array(n));
// Base Case: The last row will be the same as triangle
for (let i = 0; i < n; i++)
dp[n - 1][i] = triangle[n - 1][i];
// Calculation of the remaining rows,
// in bottom up manner
for (let i = n - 2; i >= 0; i--)
for (let j = 0; j < triangle[i].length; j++)
dp[i][j] = triangle[i][j]
+ Math.min(dp[i + 1][j],
dp[i + 1][j + 1]);
return dp[0][0];
}
const triangle = [ [ 2 ], [ 3, 9 ], [ 1, 6, 7 ] ];
console.log(minSumPath(triangle));
Using Space Optimized DP – O(n*n) Time and O(n) Space
In the above approach, we observe that each subproblem only depends on the results of the next row in the triangle, specifically the two adjacent values directly below. Thus, we can optimize the space complexity by using just a 1D array to store these values.
C++
// C++ program to Find Minimum Sum Path in a Triangle
// using Space Optimized DP
#include <iostream>
#include <vector>
using namespace std;
int minSumPath(vector<vector<int> >& triangle) {
int n = triangle.size();
// 1-D dp to store the result
vector<int> dp(n);
// Base Case: Initially dp will be the
// same as last row of matrix
for (int i = 0; i < n; i++)
dp[i] = triangle[n - 1][i];
// Calculation of the remaining rows,
// in bottom up manner.
for (int i = triangle.size() - 2; i >= 0; i--)
for (int j = 0; j < triangle[i].size(); j++)
dp[j] = triangle[i][j] + min(dp[j],
dp[j + 1]);
return dp[0];
}
int main() {
vector<vector<int> > triangle{{2},
{3, 9},
{1, 6, 7}};
cout << minSumPath(triangle);
return 0;
}
Java
// Java program to Find Minimum Sum Path in a Triangle using
// Space Optimized DP
import java.util.ArrayList;
import java.util.List;
class GfG {
static int
minSumPath(ArrayList<ArrayList<Integer> > triangle) {
int n = triangle.size();
// 1-D dp to store the result
int[] dp = new int[n];
// Base Case: Initially dp will be the
// same as last row of matrix
for (int i = 0; i < n; i++)
dp[i] = triangle.get(n - 1).get(i);
// Calculation of the remaining rows,
// in bottom up manner
for (int i = n - 2; i >= 0; i--)
for (int j = 0; j < triangle.get(i).size(); j++)
dp[j] = triangle.get(i).get(j)
+ Math.min(dp[j], dp[j + 1]);
return dp[0];
}
public static void main(String[] args) {
ArrayList<ArrayList<Integer> > triangle
= new ArrayList<>();
triangle.add(new ArrayList<>(List.of(2)));
triangle.add(new ArrayList<>(List.of(3, 9)));
triangle.add(new ArrayList<>(List.of(1, 6, 7)));
System.out.println(minSumPath(triangle));
}
}
Python
# Python program to Find Minimum Sum Path in a Triangle
# using Space Optimized DP
def minSumPath(triangle):
n = len(triangle)
# 1-D dp to store the result
dp = triangle[-1][:]
# Calculation of the remaining rows,
# in bottom up manner
for i in range(n - 2, -1, -1):
for j in range(len(triangle[i])):
dp[j] = triangle[i][j] + min(dp[j], dp[j + 1])
return dp[0]
if __name__ == "__main__":
triangle = [
[2],
[3, 9],
[1, 6, 7]
]
print(minSumPath(triangle))
C#
// C# program to Find Minimum Sum Path in a Triangle using
// Space Optimized DP
using System;
using System.Collections.Generic;
class GfG {
static int MinSumPath(List<List<int> > triangle) {
int n = triangle.Count;
// 1-D dp to store the result
int[] dp = new int[n];
// Base Case: Initially dp will be the
// same as last row of matrix
for (int i = 0; i < n; i++)
dp[i] = triangle[n - 1][i];
// Calculation of the remaining rows,
// in bottom up manner
for (int i = n - 2; i >= 0; i--)
for (int j = 0; j < triangle[i].Count; j++)
dp[j] = triangle[i][j]
+ Math.Min(dp[j], dp[j + 1]);
return dp[0];
}
static void Main() {
List<List<int> > triangle = new List<List<int> >{
new List<int>{ 2 }, new List<int>{ 3, 9 },
new List<int>{ 1, 6, 7 }
};
Console.WriteLine(MinSumPath(triangle));
}
}
JavaScript
// JavaScript program to Find Minimum Sum Path in a Triangle using
// Space Optimized DP
function minSumPath(triangle) {
const n = triangle.length;
// 1-D dp to store the result
const dp = [...triangle[n - 1]];
// Calculation of the remaining rows,
// in bottom up manner
for (let i = n - 2; i >= 0; i--) {
for (let j = 0; j < triangle[i].length; j++) {
dp[j] = triangle[i][j] + Math.min(dp[j], dp[j + 1]);
}
}
return dp[0];
}
const triangle = [
[2],
[3, 9],
[1, 6, 7]
];
console.log(minSumPath(triangle));
Similar Reads
Minimum number of edges that need to be added to form a triangle Given an undirected graph with N vertices and N edges. No two edges connect the same pair of vertices. A triangle is a set of three distinct vertices such that each pair of those vertices is connected by an edge i.e. three distinct vertices u, v and w are a triangle if the graph contains the edges (
9 min read
Bitonic Travelling Salesman Problem Given a 2D array, arr[][] denoting a list of coordinates of N vertices on 2D space that is already sorted by x-coordinates and y-coordinates, the task is to find the minimum distance of a tour that starts from the leftmost vertex, and strictly goes to the right, and then upon reaching the rightmost
15+ min read
Minimum Numbers of cells that are connected with the smallest path between 3 given cells Given coordinates of 3 cells (X1, Y1), (X2, Y2) and (X3, Y3) of a matrix. The task is to find the minimum path which connects all three of these cells and print the count of all the cells that are connected through this path. Note: Only possible moves are up, down, left and right. Examples: Input: X
7 min read
Shortest distance between a Line and a Point in a 3-D plane Given a line passing through two points A and B and an arbitrary point C in a 3-D plane, the task is to find the shortest distance between the point C and the line passing through the points A and B.Examples: Input: A = (5, 2, 1), B = (3, 1, -1), C = (0, 2, 3) Output: Shortest Distance is 5 Input: A
10 min read
1st to Kth shortest path lengths from node 1 to N in given Graph Given a directed and weighted graph of N nodes and M edges, the task is to find the 1st to Kth shortest path lengths from node 1 to N. Examples: Input: N = 4, M = 6, K = 3, edges = {{1, 2, 1}, {1, 3, 3}, {2, 3, 2}, {2, 4, 6}, {3, 2, 8}, {3, 4, 1}}Output: 4 4 7Explanation: The shortest path length fr
10 min read
Shortest distance between given nodes in a bidirectional weighted graph by removing any K edges Given a positive integer K and a weighted undirected connected graph of N nodes and E edges as an array Edges[] of the type {u, v, W} representing the edges between Node u and Node v having weight W, the task is to find the shortest distance between the two given nodes S and D after reducing the cos
15+ min read
Maximum path sum in a triangle. We have given numbers in form of a triangle, by starting at the top of the triangle and moving to adjacent numbers on the row below, find the maximum total from top to bottom. Examples : Input : 3 7 4 2 4 6 8 5 9 3 Output : 23 Explanation : 3 + 7 + 4 + 9 = 23 Input : 8 -4 4 2 2 6 1 1 1 1 Output : 19
15+ min read
Maximum path sum in an Inverted triangle | SET 2 Given numbers in form of an Inverted triangle. By starting at the bottom of the triangle and moving to adjacent numbers on the row above, find the maximum total from bottom to top.Examples: Input : 1 5 3 4 8 1 Output : 14 Input : 8 5 9 3 2 4 6 7 4 3 Output : 23 Method 1: Recursion In the previous ar
13 min read
Maximum sum of a path in a Right Number Triangle 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 Explanatio
15+ min read
Minimum Sum Path In 3-D Array Given a 3-D array arr[l][m][n], the task is to find the minimum path sum from the first cell of the array to the last cell of the array. We can only traverse to adjacent element, i.e., from a given cell (i, j, k), cells (i+1, j, k), (i, j+1, k) and (i, j, k+1) can be traversed, diagonal traversing i
11 min read