Leetcode刷题指南-子数组的最小值之和1734)不太懂

1)题目

子数组的最小值之和

要求:

给定一个整数数组 A,找到 min(B) 的总和,其中 B 的范围为 A 的每个(连续)子数组。

样例

输入:[3,1,2,4]
输出:17
解释:
子数组为 [3],[1],[2],[4],[3,1],[1,2],[2,4],[3,1,2],[1,2,4],[3,1,2,4]。
最小值为 3,1,2,4,1,1,2,1,1,1,和为 17。

2)思路

单调栈解决;
假设从数组的头部遍历,如果后面的数大于前面的数,那么这两个数构成的子数组取得肯定是前面的小的数;
如果后面的数小于前面的数,那么子数组就得取后面的数。
那么当前元素的贡献就是:
A[i] * A[i]与其前一个较少的元素之间的距离 * A[i]A[i]与其下一个较小元素之间的距离
将所有元素的贡献相加即可。

3)代码

//头文件
#pragma once
#include <iostream>
using namespace std;
#include <stack>

class Solution {
public:
    /**
     * @param A: an array
     * @return: the sum of subarray minimums
     */
    int sumSubarrayMins(vector<int> &A) {
        // Write your code here.
        int res = 0, n = A.size(), mod = 1e9 + 7, j, k;
        stack<int> s;
        for (int i = 0; i <= n; ++i) {
            while (!s.empty() && A[s.top()] > (i == n ? 0 : A[i])) {
                j = s.top(), s.pop();
                k = s.empty() ? -1 : s.top();
                res = (res + A[j] * (i - j) * (j - k)) % mod;
            }
            s.push(i);
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值