Talentd
FleetCode
Make and follow sheets.Sign in

Minimum Sum of Mountain Triplets II solution and explanation

MediumArray6 min read54.5% acceptanceUpdated 9 Apr 2026
Leetcode Weekly contest 368 - Easy & Medium - Minimum Sum of Mountain Triplets II & IPrakhar Agrawal · 10:22 · 1K viewsWatch on YouTube
9 more videos on this problem
  1. Leetcode Weekly contest 368 - Easy & Medium - Minimum Sum of Mountain Triplets II & IPrakhar Agrawal · 10:22 · 1K views
  2. 2909. Minimum Sum of Mountain Triplets II - LeetCode Python tutorialCode with Carter · 14:28 · 523 views
  3. Leetcode Weekly Contest 368 || Problems A, B, C || 2908, 2909, 2910 || CodeaticCode-a-tic · 27:35 · 480 views
  4. 2908 Minimum Sum of Mountain Triplets I 2909 Minimum Sum of Mountain Triplets II Weekly Contest 368Ashish Kumar · 9:44 · 425 views
  5. 2909. Minimum Sum of Mountain Triplets II | LeetCode Weekly Contest-368 | Fully ExplainedAlgoArtist · 8:16 · 372 views
  6. 2909. Minimum Sum of Mountain Triplets II (Leetcode Medium)Programming Live with Larry · 6:28 · 229 views
  7. 100114 Minimum Sum of Mountain Triplets II || leetcode || contest368 || weekly contest || solutionSsquare · 1:11 · 187 views
  8. Leetcode 2909. Minimum Sum of Mountain Triplets IIElite Code · 19:41 · 99 views
  9. Minimum Sum Of Mountain Triplets IIOwen Wu · 8:04 · 23 views
  10. Minimum Sum of Mountain Triplets Leetcode | Weekly Contest 368 | Solutions | Editorial | AbhinavAbhinav Awasthi · 8:02 · 1K views

The problem

You are given a 0-indexed array nums of integers.

A triplet of indices (i, j, k) is a mountain if:

  • i < j < k
  • nums[i] < nums[j] and nums[k] < nums[j]

Return the minimum possible sum of a mountain triplet of nums. If no such triplet exists, return -1.

Example 1:

Input: nums = [8,6,1,5,3]
Output: 9
Explanation: Triplet (2, 3, 4) is a mountain triplet of sum 9 since: 
- 2 < 3 < 4
- nums[2] < nums[3] and nums[4] < nums[3]
And the sum of this triplet is nums[2] + nums[3] + nums[4] = 9. It can be shown that there are no mountain triplets with a sum of less than 9.

Example 2:

Input: nums = [5,4,8,7,10,2]
Output: 13
Explanation: Triplet (1, 3, 5) is a mountain triplet of sum 13 since: 
- 1 < 3 < 5
- nums[1] < nums[3] and nums[5] < nums[3]
And the sum of this triplet is nums[1] + nums[3] + nums[5] = 13. It can be shown that there are no mountain triplets with a sum of less than 13.

Example 3:

Input: nums = [6,5,4,3,4,5]
Output: -1
Explanation: It can be shown that there are no mountain triplets in nums.

Constraints:

  • 3 <= nums.length <= 105
  • 1 <= nums[i] <= 108

Approach overview

Problem Overview: You are given an integer array and must find a triplet (i, j, k) such that i < j < k, nums[i] < nums[j], and nums[k] < nums[j]. The element at index j acts as the mountain peak. Among all valid mountain triplets, return the minimum possible value of nums[i] + nums[j] + nums[k]. If no valid triplet exists, return -1. The challenge is efficiently identifying smaller elements on both sides of every potential peak.

Approach 1: Peak and Two-Pointer Strategy (O(n²) time, O(1) space)

Treat every index j as the potential mountain peak. For each peak, scan the left side to find the smallest value nums[i] where i < j and nums[i] < nums[j]. Then scan the right side to find the smallest value nums[k] where k > j and nums[k] < nums[j]. If both exist, compute the sum and track the minimum across all peaks. This approach relies only on direct iteration and works well for understanding the constraint structure of the problem. However, repeatedly scanning both sides for every peak leads to quadratic time complexity. You mainly use basic array traversal with pointer movement similar to manual two‑pointer exploration.

Approach 2: Optimized Precomputation Method (O(n) time, O(n) space)

The key observation: for every potential peak j, you only need the smallest valid value on the left and the smallest valid value on the right. Precompute a prefix minimum array where leftMin[j] stores the smallest element seen before index j. Similarly compute a suffix minimum array where rightMin[j] stores the smallest element to the right of j. Then iterate through the array once and treat each index as the peak. A valid mountain exists only if leftMin[j] < nums[j] and rightMin[j] < nums[j]. When both conditions hold, calculate leftMin[j] + nums[j] + rightMin[j] and update the global minimum.

This preprocessing removes repeated scanning. Each element is processed a constant number of times: once during prefix computation, once during suffix computation, and once during the peak evaluation pass. The result is linear time complexity with predictable memory usage, making it the most practical approach for large arrays.

Recommended for interviews: The optimized precomputation method is the expected solution. Interviewers want to see that you convert repeated searches into prefix/suffix preprocessing, a common pattern in array problems. Mentioning the naive scanning approach first shows you understand the problem structure, while implementing the O(n) optimization demonstrates strong algorithmic thinking.

Approach 1: Peak and Two-Pointer Strategy

This approach focuses on identifying the peak elements first and then applies a two-pointer strategy to find the minimum sum of a mountain triplet. The idea is to try each element as the peak (the middle element of a triplet) and find the smallest elements on either side under the given constraints.

def minMountainTripletSum(nums):
    min_sum = float('inf')
    for j in range(1, len(nums) - 1):
        left_min = float('inf')
        for i in range(j):
            if nums[i] < nums[j] and nums[i] < left_min:
                left_min = nums[i]
        right_min = float('inf')
        for k in range(j + 1, len(nums)):
            if nums[k] < nums[j] and nums[k] < right_min:
                right_min = nums[k]
        if left_min != float('inf') and right_min != float('inf'):
            current_sum = left_min + nums[j] + right_min
            min_sum = min(min_sum, current_sum)
    return -1 if min_sum == float('inf') else min_sum

nums = [8, 6, 1, 5, 3]
print(minMountainTripletSum(nums))
import java.util.*;

public class Main {
    public static int minMountainTripletSum(int[] nums) {
        int minSum = Integer.MAX_VALUE;
        for (int j = 1; j < nums.length - 1; j++) {
            int left_min = Integer.MAX_VALUE;
            for (int i = 0; i < j; i++) {
                if (nums[i] < nums[j] && nums[i] < left_min) {
                    left_min = nums[i];
                }
            }
            int right_min = Integer.MAX_VALUE;
            for (int k = j + 1; k < nums.length; k++) {
                if (nums[k] < nums[j] && nums[k] < right_min) {
                    right_min = nums[k];
                }
            }
            if (left_min != Integer.MAX_VALUE && right_min != Integer.MAX_VALUE) {
                int sum = left_min + nums[j] + right_min;
                if (sum < minSum) {
                    minSum = sum;
                }
            }
        }
        return minSum == Integer.MAX_VALUE ? -1 : minSum;
    }

    public static void main(String[] args) {
        int[] nums = {8, 6, 1, 5, 3};
        System.out.println(minMountainTripletSum(nums));
    }
}
#include <vector>
#include <iostream>
#include <climits>
using namespace std;

int minMountainTripletSum(vector<int>& nums) {
    int minSum = INT_MAX;
    for (int j = 1; j < nums.size() - 1; j++) {
        int left_min = INT_MAX;
        for (int i = 0; i < j; i++) {
            if (nums[i] < nums[j] && nums[i] < left_min) {
                left_min = nums[i];
            }
        }
        int right_min = INT_MAX;
        for (int k = j + 1; k < nums.size(); k++) {
            if (nums[k] < nums[j] && nums[k] < right_min) {
                right_min = nums[k];
            }
        }
        if (left_min != INT_MAX && right_min != INT_MAX) {
            int sum = left_min + nums[j] + right_min;
            if (sum < minSum) {
                minSum = sum;
            }
        }
    }
    return minSum == INT_MAX ? -1 : minSum;
}

int main() {
    vector<int> nums = {8, 6, 1, 5, 3};
    cout << minMountainTripletSum(nums) << endl;
    return 0;
}
function minMountainTripletSum(nums) {
    let minSum = Number.MAX_VALUE;
    for (let j = 1; j < nums.length - 1; j++) {
        let leftMin = Number.MAX_VALUE;
        for (let i = 0; i < j; i++) {
            if (nums[i] < nums[j] && nums[i] < leftMin) {
                leftMin = nums[i];
            }
        }
        let rightMin = Number.MAX_VALUE;
        for (let k = j + 1; k < nums.length; k++) {
            if (nums[k] < nums[j] && nums[k] < rightMin) {
                rightMin = nums[k];
            }
        }
        if (leftMin !== Number.MAX_VALUE && rightMin !== Number.MAX_VALUE) {
            minSum = Math.min(minSum, leftMin + nums[j] + rightMin);
        }
    }
    return minSum === Number.MAX_VALUE ? -1 : minSum;
}

const nums = [8, 6, 1, 5, 3];
console.log(minMountainTripletSum(nums));
#include <stdio.h>
#include <limits.h>

int minMountainTripletSum(int* nums, int numsSize) {
    int minSum = INT_MAX;
    for (int j = 1; j < numsSize - 1; j++) {
        int left_min = INT_MAX;
        for (int i = 0; i < j; i++) {
            if (nums[i] < nums[j] && nums[i] < left_min) {
                left_min = nums[i];
            }
        }
        int right_min = INT_MAX;
        for (int k = j + 1; k < numsSize; k++) {
            if (nums[k] < nums[j] && nums[k] < right_min) {
                right_min = nums[k];
            }
        }
        if (left_min != INT_MAX && right_min != INT_MAX) {
            int sum = left_min + nums[j] + right_min;
            if (sum < minSum) {
                minSum = sum;
            }
        }
    }
    return minSum == INT_MAX ? -1 : minSum;
}

int main() {
    int nums[] = {8, 6, 1, 5, 3};
    int numsSize = sizeof(nums) / sizeof(nums[0]);
    printf("%d\n", minMountainTripletSum(nums, numsSize));
    return 0;
}
using System;

public class Program {
    public static int MinMountainTripletSum(int[] nums) {
        int minSum = int.MaxValue;
        for (int j = 1; j < nums.Length - 1; j++) {
            int leftMin = int.MaxValue;
            for (int i = 0; i < j; i++) {
                if (nums[i] < nums[j] && nums[i] < leftMin) {
                    leftMin = nums[i];
                }
            }
            int rightMin = int.MaxValue;
            for (int k = j + 1; k < nums.Length; k++) {
                if (nums[k] < nums[j] && nums[k] < rightMin) {
                    rightMin = nums[k];
                }
            }
            if (leftMin != int.MaxValue && rightMin != int.MaxValue) {
                int sum = leftMin + nums[j] + rightMin;
                minSum = Math.Min(minSum, sum);
            }
        }
        return minSum == int.MaxValue ? -1 : minSum;
    }

    public static void Main() {
        int[] nums = {8, 6, 1, 5, 3};
        Console.WriteLine(MinMountainTripletSum(nums));
    }
}

In the Python version, we utilize the same core strategy: choosing each point as a possible peak and determining the smallest qualifying elements for the triplet sum. This repeats for every middle index.

Complexity

Time Complexity: O(n^2)
Space Complexity: O(1)

Try this approach in the editor

Approach 2: Optimized Precomputation Method

This method reduces the complexity by precomputing the smallest elements to the left and right for each potential peak. We make use of two auxiliary arrays to store these values, thereby reducing redundant computation within the nested loops.

def minMountainTripletSum(nums):
    left_min = [float('inf')] * len(nums)
    right_min = [float('inf')] * len(nums)

    for i in range(1, len(nums)):
        left_min[i] = min(left_min[i - 1], nums[i - 1])

    for i in range(len(nums) - 2, -1, -1):
        right_min[i] = min(right_min[i + 1], nums[i + 1])

    min_sum = float('inf')
    for j in range(1, len(nums) - 1):
        if left_min[j] < nums[j] and nums[j] > right_min[j]:
            min_sum = min(min_sum, left_min[j] + nums[j] + right_min[j])

    return -1 if min_sum == float('inf') else min_sum

nums = [8, 6, 1, 5, 3]
print(minMountainTripletSum(nums))
import java.util.*;

public class Main {
    public static int minMountainTripletSum(int[] nums) {
        int[] left_min = new int[nums.length];
        int[] right_min = new int[nums.length];
        Arrays.fill(left_min, Integer.MAX_VALUE);
        Arrays.fill(right_min, Integer.MAX_VALUE);

        for (int i = 1; i < nums.length; i++) {
            left_min[i] = Math.min(left_min[i - 1], nums[i - 1]);
        }
        for (int i = nums.length - 2; i >= 0; i--) {
            right_min[i] = Math.min(right_min[i + 1], nums[i + 1]);
        }
        int minSum = Integer.MAX_VALUE;
        for (int j = 1; j < nums.length - 1; j++) {
            if (left_min[j] < nums[j] && nums[j] > right_min[j]) {
                minSum = Math.min(minSum, left_min[j] + nums[j] + right_min[j]);
            }
        }
        return minSum == Integer.MAX_VALUE ? -1 : minSum;
    }

    public static void main(String[] args) {
        int[] nums = {8, 6, 1, 5, 3};
        System.out.println(minMountainTripletSum(nums));
    }
}
#include <vector>
#include <iostream>
#include <climits>
using namespace std;

int minMountainTripletSum(vector<int>& nums) {
    vector<int> left_min(nums.size(), INT_MAX);
    vector<int> right_min(nums.size(), INT_MAX);

    for (int i = 1; i < nums.size(); i++) {
        left_min[i] = min(left_min[i - 1], nums[i - 1]);
    }
    for (int i = nums.size() - 2; i >= 0; i--) {
        right_min[i] = min(right_min[i + 1], nums[i + 1]);
    }
    int minSum = INT_MAX;
    for (int j = 1; j < nums.size() - 1; j++) {
        if (left_min[j] < nums[j] && nums[j] > right_min[j]) {
            minSum = min(minSum, left_min[j] + nums[j] + right_min[j]);
        }
    }
    return minSum == INT_MAX ? -1 : minSum;
}

int main() {
    vector<int> nums = {8, 6, 1, 5, 3};
    cout << minMountainTripletSum(nums) << endl;
    return 0;
}
function minMountainTripletSum(nums) {
    let leftMin = new Array(nums.length).fill(Number.MAX_VALUE);
    let rightMin = new Array(nums.length).fill(Number.MAX_VALUE);

    for (let i = 1; i < nums.length; i++) {
        leftMin[i] = Math.min(leftMin[i - 1], nums[i - 1]);
    }

    for (let i = nums.length - 2; i >= 0; i--) {
        rightMin[i] = Math.min(rightMin[i + 1], nums[i + 1]);
    }

    let minSum = Number.MAX_VALUE;
    for (let j = 1; j < nums.length - 1; j++) {
        if (leftMin[j] < nums[j] && nums[j] > rightMin[j]) {
            minSum = Math.min(minSum, leftMin[j] + nums[j] + rightMin[j]);
        }
    }
    return minSum === Number.MAX_VALUE ? -1 : minSum;
}

const nums = [8, 6, 1, 5, 3];
console.log(minMountainTripletSum(nums));
#include <stdio.h>
#include <limits.h>

int minMountainTripletSum(int* nums, int numsSize) {
    int left_min[numsSize];
    int right_min[numsSize];

    left_min[0] = INT_MAX;
    for (int i = 1; i < numsSize; i++) {
        left_min[i] = nums[i - 1] < left_min[i - 1] ? nums[i - 1] : left_min[i - 1];
    }

    right_min[numsSize - 1] = INT_MAX;
    for (int i = numsSize - 2; i >= 0; i--) {
        right_min[i] = nums[i + 1] < right_min[i + 1] ? nums[i + 1] : right_min[i + 1];
    }

    int minSum = INT_MAX;
    for (int j = 1; j < numsSize - 1; j++) {
        if (left_min[j] < nums[j] && right_min[j] < nums[j]) {
            int sum = left_min[j] + nums[j] + right_min[j];
            if (sum < minSum) {
                minSum = sum;
            }
        }
    }
    return minSum == INT_MAX ? -1 : minSum;
}

int main() {
    int nums[] = {8, 6, 1, 5, 3};
    int numsSize = sizeof(nums) / sizeof(nums[0]);
    printf("%d\n", minMountainTripletSum(nums, numsSize));
    return 0;
}
using System;

public class Program {
    public static int MinMountainTripletSum(int[] nums) {
        int[] leftMin = new int[nums.Length];
        int[] rightMin = new int[nums.Length];
        for (int i = 0; i < leftMin.Length; i++) leftMin[i] = int.MaxValue;
        for (int i = 0; i < rightMin.Length; i++) rightMin[i] = int.MaxValue;

        for (int i = 1; i < nums.Length; i++) {
            leftMin[i] = Math.Min(leftMin[i - 1], nums[i - 1]);
        }

        for (int i = nums.Length - 2; i >= 0; i--) {
            rightMin[i] = Math.Min(rightMin[i + 1], nums[i + 1]);
        }

        int minSum = int.MaxValue;
        for (int j = 1; j < nums.Length - 1; j++) {
            if (leftMin[j] < nums[j] && nums[j] > rightMin[j]) {
                minSum = Math.Min(minSum, leftMin[j] + nums[j] + rightMin[j]);
            }
        }
        return minSum == int.MaxValue ? -1 : minSum;
    }

    public static void Main() {
        int[] nums = {8, 6, 1, 5, 3};
        Console.WriteLine(MinMountainTripletSum(nums));
    }
}

This Python solution improves efficiency by precomputing decreasing values spanning both sides of each entity, thus converting the overall complexity to linear scale.

Complexity

Time Complexity: O(n)
Space Complexity: O(n)

Try this approach in the editor

Approach 3: Preprocessing + Enumeration

We can preprocess the minimum value on the right side of each position and record it in the array right[i], where right[i] represents the minimum value in nums[i+1..n-1].

Next, we enumerate the middle element nums[i] of the mountain triplet from left to right, and use a variable left to represent the minimum value in ums[0..i-1], and a variable ans to represent the current minimum element sum found. For each i, we need to find the element nums[i] that satisfies left < nums[i] and right[i+1] < nums[i], and update ans.

Finally, if ans is still the initial value, it means that there is no mountain triplet, and we return -1.

The time complexity is O(n), and the space complexity is O(n). Here, n is the length of the array.

function minimumSum(nums: number[]): number {
    const n = nums.length;
    const right: number[] = Array(n + 1).fill(Infinity);
    for (let i = n - 1; ~i; --i) {
        right[i] = Math.min(right[i + 1], nums[i]);
    }
    let [ans, left] = [Infinity, Infinity];
    for (let i = 0; i < n; ++i) {
        if (left < nums[i] && right[i + 1] < nums[i]) {
            ans = Math.min(ans, left + nums[i] + right[i + 1]);
        }
        left = Math.min(left, nums[i]);
    }
    return ans === Infinity ? -1 : ans;
}
func minimumSum(nums []int) int {
	n := len(nums)
	const inf = 1 << 30
	right := make([]int, n+1)
	right[n] = inf
	for i := n - 1; i >= 0; i-- {
		right[i] = min(right[i+1], nums[i])
	}
	ans, left := inf, inf
	for i, x := range nums {
		if left < x && right[i+1] < x {
			ans = min(ans, left+x+right[i+1])
		}
		left = min(left, x)
	}
	if ans == inf {
		return -1
	}
	return ans
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Peak and Two-Pointer Strategy

Time Complexity: O(n^2)
Space Complexity: O(1)

Optimized Precomputation Method

Time Complexity: O(n)
Space Complexity: O(n)

Preprocessing + Enumeration–

Complexity analysis

ApproachTimeSpaceWhen to Use
Peak and Two-Pointer StrategyO(n²)O(1)Useful for understanding the problem structure or when input size is small
Optimized Precomputation MethodO(n)O(n)Best choice for interviews and large arrays; avoids repeated scanning by using prefix and suffix minimums

Frequently asked questions

Is Minimum Sum of Mountain Triplets II easy or hard?

Minimum Sum of Mountain Triplets II is generally considered a medium-level array problem. The brute-force idea is simple, but recognizing that prefix and suffix minimum preprocessing reduces the complexity to O(n) requires stronger algorithmic intuition.

Minimum Sum of Mountain Triplets II Python/Java solution

Python, Java, C++, C, C#, and JavaScript implementations typically follow the same pattern: compute prefix minimums, compute suffix minimums, then iterate through each index as a peak candidate. The logic remains identical across languages, with overall O(n) time complexity.

How to solve Minimum Sum of Mountain Triplets II in O(n)?

Precompute the smallest element to the left of every index and the smallest element to the right using prefix and suffix arrays. Then iterate through each index j as a peak and check if both sides contain values smaller than nums[j]. When they do, compute the sum and keep the minimum. Each element is processed a constant number of times, giving O(n) complexity.

What is the best approach for Minimum Sum of Mountain Triplets II?

The optimal approach uses prefix and suffix minimum precomputation. For each index j treated as the peak, track the smallest value to its left and right. If both are smaller than nums[j], compute the triplet sum. This method runs in O(n) time and is the solution most interviewers expect.

Is Minimum Sum of Mountain Triplets II asked at Google/Amazon/Meta?

Mountain or peak-based array problems frequently appear in interviews at companies like Amazon, Google, and Meta. Variants that require prefix or suffix preprocessing are common because they test optimization skills and pattern recognition.

What data structure is used in Minimum Sum of Mountain Triplets II?

The problem primarily uses arrays for prefix minimum and suffix minimum preprocessing. These arrays allow constant-time lookups for the smallest value on either side of a potential peak while iterating through the original array.

What is the time complexity of Minimum Sum of Mountain Triplets II?

The optimized solution runs in O(n) time by preprocessing prefix and suffix minimum arrays and scanning the array once more to evaluate peaks. A straightforward scanning approach that checks both sides for every index takes O(n²) time.

Comments

Now write it yourselfClose this page and solve Minimum Sum of Mountain Triplets II in the editor, without looking.
Practise Minimum Sum of Mountain Triplets II