普通视图

发现新文章,点击刷新页面。
昨天 — 2025年4月3日首页

【小羊肖恩】从暴力到贪心:想清楚贪心的每一步,就可以顺序遍历啦~!

作者 Yawn_Sean
2023年10月1日 12:23

对于这个问题,数据范围是 $100$ 的情况,我们可以直接暴力枚举所有合法的 $(i, j, k)$ 三元组,看其值取最大即可。 注意要求如果是负值时,返回 $0$.

时间复杂度为 $\mathcal{O}(n^3)$.

具体代码如下——

###Python

class Solution:
    def maximumTripletValue(self, nums: List[int]) -> int:
        n = len(nums)
        ans = 0
        for k in range(n):
            for j in range(k):
                for i in range(j):
                    ans = max(ans, (nums[i] - nums[j]) * nums[k])
        return ans

接下来我们思考如何处理 $n \leq 10^5$ 的情况。

首先,输出的数值最小为 $0$,同时数组中每个元素均为正数,因此,我们要让 (nums[i] - nums[j]) * nums[k] 最大,只需要对于固定的 $k$ 找到其前面 nums[i] - nums[j] 的最大值。

为了使得 nums[i] - nums[j] 尽可能大,我们需要对于固定的 j 找到其前面最大的 nums[i] 再将两者相减。

以上逻辑可见代码注释。

因此我们只需要维护三个东西:到当前位置的最大值,到当前位置为止最大的 nums[i] - nums[j],到当前位置为止最大的 (nums[i] - nums[j]) * nums[k]. 而从上面的分析可以看出,这些都可以遍历过程中实现。

因此时间复杂度是 $\mathcal{O}(n)$ 的。

具体代码如下——

###Python

class Solution:
    def maximumTripletValue(self, nums: List[int]) -> int:
        # 当前最大值
        curr_max = 0
        # 当前最大的 nums[i] - nums[j]
        curr_v = 0
        # 当前最大的 (nums[i] - nums[j]) * nums[k]
        ans = 0
        n = len(nums)
        
        for i in range(n):
            # 答案的最大值根据最大的 nums[i] - nums[j] 和当前数值的乘积更新
            ans = max(ans, nums[i] * curr_v)
            # nums[i] - nums[j] 的最大值根据此前最大值减去当前数值更新
            curr_v = max(curr_v, curr_max - nums[i])
            # 更新前缀最大值
            curr_max = max(curr_max, nums[i])
        return ans
❌
❌