2012. 数组美丽值求和【动态规划】

对于所有 0≤j<i 且 i<k≤n−1,满足 nums[j]<nums[i]<nums[k]

题目的这个要求,相当于:

nums[i] 要大于 i 左边的所有数,也就是大于前缀 [0,i−1] 中的最大值。
nums[i] 要小于 i 右边的所有数,也就是小于后缀 [i+1,n−1] 中的最小值

这可以通过遍历算出来。

定义 sufMin[i] 表示后缀 [i,n−1] 中的最小值。

那么 sufMin[i] 等于 nums[i] 与后缀 [i+1,n−1] 中的最小值,二者取最小值,即

sufMin[i]=min(nums[i],sufMin[i+1])
注意上式需要从右到左遍历 nums 计算。

对于前缀最大值,也同理。

我们可以在从左到右遍历 nums 的过程中,维护前缀最大值 preMax。注意这只需要一个变量,因为我们可以一边计算 preMax,一边计算答案。

class Solution:
    def sumOfBeauties(self, nums: List[int]) -> int:
        n = len(nums)
        suf_min = [0] * n  # 后缀最小值,题目中num>0
        suf_min[n - 1] = nums[n - 1]
        # sufMin[i]代表的是从索引i开始到数组末尾的最小值。
        # 而计算这个值的方法是,当前元素nums[i]和下一个位置的sufMin[i+1]中的较小者。
        # 这意味着,如果我们从数组的最后一个元素开始向前遍历,就可以逐步构建出每个位置的sufMin值。
        # 例如,考虑一个简单的数组,比如[3,1,4,2]。按照用户的方法,从右向左计算:
            # 对于i=3(最后一个元素),sufMin[3] = nums[3] = 2。
            # i=2时,sufMin[2] = min(4, sufMin[3]) = min(4,2) = 2。
            # i=1时,sufMin[1] = min(1, sufMin[2]) = min(1,2) = 1。
            # i=0时,sufMin[0] = min(3, sufMin[1]) = min(3,1) = 1。
        for i in range(n - 2, 1, -1):
            suf_min[i] = min(suf_min[i + 1], nums[i])

        ans = 0
        # 前缀最大值
        pre_max = nums[0]  
        for i in range(1, n - 1):
            x = nums[i]
            # 此时 pre_max 表示 [0, i-1] 中的最大值
            if pre_max < x < suf_min[i + 1]:
                ans += 2
            elif nums[i - 1] < x < nums[i + 1]:
                ans += 1
            # 更新后 pre_max 表示 [0, i] 中的最大值
            pre_max = max(pre_max, x)
        return ans

作者:灵茶山艾府
链接:https://leetcode.cn/problems/sum-of-beauty-in-the-array/solutions/1006001/qian-zhui-zui-da-zhi-hou-zhui-zui-xiao-z-h9qz/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值