Minimum Sum of Mountain Triplets II
MediumUpdated: Aug 2, 2025
Practice on:
Problem
You are given a 0-indexed array nums of integers.
A triplet of indices (i, j, k) is a mountain if:
i < j < knums[i] < nums[j]andnums[k] < nums[j]
Return theminimum possible sum of a mountain triplet of nums. If no such triplet exists, return -1.
Examples
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 <= 10^51 <= nums[i] <= 10^8
Solution
Method 1 – Prefix and Suffix Min Arrays
Intuition
For each possible middle index j, find the smallest nums[i] to the left of j (where nums[i] < nums[j]) and the smallest nums[k] to the right of j (where nums[k] < nums[j]). The minimum sum among all valid triplets is the answer.
Approach
- For each index, build prefix min array for left candidates (nums[i] < nums[j]).
- Build suffix min array for right candidates (nums[k] < nums[j]).
- For each j, if both left and right candidates exist, update the answer with their sum.
- Return the minimum sum found, or -1 if no triplet exists.
Code
C++
class Solution {
public:
int minimumSum(vector<int>& nums) {
int n = nums.size(), ans = INT_MAX;
vector<int> left(n, INT_MAX), right(n, INT_MAX);
int minl = INT_MAX;
for (int i = 0; i < n; ++i) {
left[i] = minl;
if (nums[i] < minl) minl = nums[i];
}
int minr = INT_MAX;
for (int i = n-1; i >= 0; --i) {
right[i] = minr;
if (nums[i] < minr) minr = nums[i];
}
for (int j = 1; j < n-1; ++j) {
if (left[j] < nums[j] && right[j] < nums[j])
ans = min(ans, left[j] + nums[j] + right[j]);
}
return ans == INT_MAX ? -1 : ans;
}
};
Go
func minimumSum(nums []int) int {
n := len(nums)
left := make([]int, n)
right := make([]int, n)
minl := 1<<31-1
for i := 0; i < n; i++ {
left[i] = minl
if nums[i] < minl { minl = nums[i] }
}
minr := 1<<31-1
for i := n-1; i >= 0; i-- {
right[i] = minr
if nums[i] < minr { minr = nums[i] }
}
ans := 1<<31-1
for j := 1; j < n-1; j++ {
if left[j] < nums[j] && right[j] < nums[j] {
sum := left[j] + nums[j] + right[j]
if sum < ans { ans = sum }
}
}
if ans == 1<<31-1 { return -1 }
return ans
}
Java
class Solution {
public int minimumSum(int[] nums) {
int n = nums.length, ans = Integer.MAX_VALUE;
int[] left = new int[n], right = new int[n];
int minl = Integer.MAX_VALUE;
for (int i = 0; i < n; i++) {
left[i] = minl;
if (nums[i] < minl) minl = nums[i];
}
int minr = Integer.MAX_VALUE;
for (int i = n-1; i >= 0; i--) {
right[i] = minr;
if (nums[i] < minr) minr = nums[i];
}
for (int j = 1; j < n-1; j++) {
if (left[j] < nums[j] && right[j] < nums[j])
ans = Math.min(ans, left[j] + nums[j] + right[j]);
}
return ans == Integer.MAX_VALUE ? -1 : ans;
}
}
Kotlin
class Solution {
fun minimumSum(nums: IntArray): Int {
val n = nums.size
val left = IntArray(n)
val right = IntArray(n)
var minl = Int.MAX_VALUE
for (i in 0 until n) {
left[i] = minl
if (nums[i] < minl) minl = nums[i]
}
var minr = Int.MAX_VALUE
for (i in n-1 downTo 0) {
right[i] = minr
if (nums[i] < minr) minr = nums[i]
}
var ans = Int.MAX_VALUE
for (j in 1 until n-1) {
if (left[j] < nums[j] && right[j] < nums[j])
ans = minOf(ans, left[j] + nums[j] + right[j])
}
return if (ans == Int.MAX_VALUE) -1 else ans
}
}
Python
class Solution:
def minimumSum(self, nums: list[int]) -> int:
n = len(nums)
left = [float('inf')] * n
right = [float('inf')] * n
minl = float('inf')
for i in range(n):
left[i] = minl
if nums[i] < minl: minl = nums[i]
minr = float('inf')
for i in range(n-1, -1, -1):
right[i] = minr
if nums[i] < minr: minr = nums[i]
ans = float('inf')
for j in range(1, n-1):
if left[j] < nums[j] and right[j] < nums[j]:
ans = min(ans, left[j] + nums[j] + right[j])
return -1 if ans == float('inf') else ans
Rust
impl Solution {
pub fn minimum_sum(nums: Vec<i32>) -> i32 {
let n = nums.len();
let mut left = vec![i32::MAX; n];
let mut right = vec![i32::MAX; n];
let mut minl = i32::MAX;
for i in 0..n {
left[i] = minl;
if nums[i] < minl { minl = nums[i]; }
}
let mut minr = i32::MAX;
for i in (0..n).rev() {
right[i] = minr;
if nums[i] < minr { minr = nums[i]; }
}
let mut ans = i32::MAX;
for j in 1..n-1 {
if left[j] < nums[j] && right[j] < nums[j] {
ans = ans.min(left[j] + nums[j] + right[j]);
}
}
if ans == i32::MAX { -1 } else { ans }
}
}
TypeScript
class Solution {
minimumSum(nums: number[]): number {
const n = nums.length;
const left = Array(n).fill(Infinity);
const right = Array(n).fill(Infinity);
let minl = Infinity;
for (let i = 0; i < n; i++) {
left[i] = minl;
if (nums[i] < minl) minl = nums[i];
}
let minr = Infinity;
for (let i = n-1; i >= 0; i--) {
right[i] = minr;
if (nums[i] < minr) minr = nums[i];
}
let ans = Infinity;
for (let j = 1; j < n-1; j++) {
if (left[j] < nums[j] && right[j] < nums[j])
ans = Math.min(ans, left[j] + nums[j] + right[j]);
}
return ans === Infinity ? -1 : ans;
}
}
Complexity
- ⏰ Time complexity:
O(n)— One pass for prefix, one for suffix, one for answer. - 🧺 Space complexity:
O(n)— For left and right arrays.