LeetCode 2908.元素和最小的山形三元组 I:贪心(两次遍历)——双O(n)复杂度

【LetMeFly】2908.元素和最小的山形三元组 I:贪心(两次遍历)——双O(n)复杂度

力扣题目链接:https://leetcode.cn/problems/minimum-sum-of-mountain-triplets-i/

给你一个下标从 0 开始的整数数组 nums

如果下标三元组 (i, j, k) 满足下述全部条件,则认为它是一个 山形三元组

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

请你找出 nums元素和最小 的山形三元组,并返回其 元素和 。如果不存在满足条件的三元组,返回 -1

 

示例 1:

输入:nums = [8,6,1,5,3]
输出:9
解释:三元组 (2, 3, 4) 是一个元素和等于 9 的山形三元组,因为: 
- 2 < 3 < 4
- nums[2] < nums[3] 且 nums[4] < nums[3]
这个三元组的元素和等于 nums[2] + nums[3] + nums[4] = 9 。可以证明不存在元素和小于 9 的山形三元组。

示例 2:

输入:nums = [5,4,8,7,10,2]
输出:13
解释:三元组 (1, 3, 5) 是一个元素和等于 13 的山形三元组,因为: 
- 1 < 3 < 5 
- nums[1] < nums[3] 且 nums[5] < nums[3]
这个三元组的元素和等于 nums[1] + nums[3] + nums[5] = 13 。可以证明不存在元素和小于 13 的山形三元组。

示例 3:

输入:nums = [6,5,4,3,4,5]
输出:-1
解释:可以证明 nums 中不存在山形三元组。

 

提示:

  • 3 <= nums.length <= 50
  • 1 <= nums[i] <= 50

解题方法:两次遍历

我们可以枚举中间j的位置。对于nums[j],最优解是加上左边所有数中最小的那个 再加上 右边所有数中最小的那个。(如果两边最小都小于nums[j]的话)

因此我们可以开辟一个leftMin数组,其中leftMin[i]nums[0]nums[i]中所有值的最小值。这个数组只需要遍历一遍nums即可得到。

接着从右往左遍历j的位置,并使用一个变量rightMin记录右边的最小值,遍历完成后即可得知所有合法山形三元组中最小的那个了。

  • 时间复杂度 O ( n ) O(n) O(n)
  • 空间复杂度 O ( n ) O(n) O(n)

AC代码

C++
class Solution {
public:
    int minimumSum(vector<int>& nums) {
        vector<int> leftMin(nums.size());
        leftMin[0] = nums[0];
        for (int i = 1; i < nums.size(); i++) {
            leftMin[i] = min(nums[i], leftMin[i - 1]);
        }
        int rightMin = nums.back();
        int ans = 1e7;
        for (int i = nums.size() - 2; i > 0; i--) {
            if (nums[i] > leftMin[i - 1] && nums[i] > rightMin) {
                ans = min(ans, nums[i] + leftMin[i - 1] + rightMin);
            }
            rightMin = min(rightMin, nums[i]);
        }
        return ans == 1e7 ? -1 : ans;
    }
};
Python
# from typing import List

class Solution:
    def minimumSum(self, nums: List[int]) -> int:
        leftMin = [0] * len(nums)
        leftMin[0] = nums[0]
        for i in range(1, len(nums)):
            leftMin[i] = min(leftMin[i - 1], nums[i])
        rightMin = nums[-1]
        ans = 1_000_000
        for i in range(len(nums) - 2, 0, -1):
            if nums[i] > leftMin[i - 1] and nums[i] > rightMin:
                ans = min(ans, nums[i] + leftMin[i - 1] + rightMin)
            rightMin = min(rightMin, nums[i])
        return ans if ans < 1_000_000 else -1

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/137151595

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-30 22:56:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-30 22:56:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-30 22:56:02       82 阅读
  4. Python语言-面向对象

    2024-03-30 22:56:02       91 阅读

热门阅读

  1. 常用的 Git 命令

    2024-03-30 22:56:02       36 阅读
  2. ChatGPT指南:如何利用AI撰写优质学术论文

    2024-03-30 22:56:02       45 阅读
  3. IP地址的组成

    2024-03-30 22:56:02       40 阅读
  4. python习题小练习(挑战全对)

    2024-03-30 22:56:02       39 阅读
  5. darknet | darknet之nms do_nms_sort详解

    2024-03-30 22:56:02       44 阅读
  6. MyBatis 流式查询

    2024-03-30 22:56:02       41 阅读
  7. 智算AI平台介绍:初识volcano

    2024-03-30 22:56:02       40 阅读
  8. uniapp中怎么引入echarts(最简单)

    2024-03-30 22:56:02       36 阅读
  9. 【Ncaos】Oracle数据库支持

    2024-03-30 22:56:02       45 阅读
  10. Python装饰器与生成器:从原理到实践

    2024-03-30 22:56:02       44 阅读