⭐ 解法
class Solution:
def minimumSum(self, nums: List[int]) -> int:
# left[i] 前缀数组中的最小值
# 从 右往左 遍历, 当一个数 比左右两边都大时, 找到一个山形数组
n = len(nums)
left = [nums[0]] # 前缀最小值
for i in range(1, n):
left.append(min(nums[i], left[-1]))
min_right = nums[n - 1]
ret = inf
for i in range(n - 2, 0, -1): # i 中间的数
if nums[i] > max(min_right, left[i]): # 若是 不满足, 说明不能 当中间的数
ret = min(ret, nums[i] + min_right + left[i])
min_right = min(min_right, nums[i])
return -1 if ret == inf else ret
class Solution {//两次遍历: O(n) O(n)
public:
int minimumSum(vector<int>& nums) {
int n = nums.size();
vector<int> left;
left.emplace_back(nums[0]);
for (int i = 1; i < n; ++i){
left.emplace_back(min(left.back(), nums[i])); // 要是这里 存储的是 nums[i], 说明 nums[i] 不适合当 中间
}
int min_right = nums[n - 1];
int ret = INT_MAX;
for (int i = n - 2; i >= 1; --i){// 中间值
if (nums[i] > max(min_right, left[i])){
ret = min(ret, nums[i] + min_right + left[i]);
}
min_right = min(nums[i], min_right); // 记得 维护 min_right
}
return ret == INT_MAX ? -1 : ret;
}
};
—————————————— 直觉解法
class Solution:
def minimumSum(self, nums: List[int]) -> int:
n = len(nums) # 固定 left, 固定 i ,找right
left = 0
i = 1
right = 2
ret = inf
while left < n - 2: # n - 2 n - 1
i = left + 1
while i < n - 1:
if nums[left] < nums[i]:
right = i + 1
while right < n:
if nums[right] < nums[i]:
ret = min(ret, nums[left] + nums[i] + nums[right])
right += 1
i += 1
left += 1
return -1 if ret == inf else ret