首页 > 其他分享 >907. 子数组的最小值之和

907. 子数组的最小值之和

时间:2022-10-28 12:24:19浏览次数:72  
标签:arr 907 int st 最小值 数组 empty size

907. 子数组的最小值之和

给定一个整数数组 arr,找到 min(b) 的总和,其中 b 的范围为 arr 的每个(连续)子数组。
由于答案可能很大,因此 返回答案模 10^9 + 7 。

示例一
输入:arr = [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。

题目链接

暴力

class Solution {
public:
    int sumSubarrayMins(vector<int>& arr) {
        int res=0;
        for(int i=0;i<arr.size();i++){
            int temp=arr[i];
            for(int j=i;j<arr.size();j++){
                temp=min(temp,arr[j]);
                //cout<<temp<<" ";
                res=(res+temp)%1000000007;
            }
            cout<<endl;
        }
        return res;
    }
};

单调栈+贡献法

OX3F题解

class Solution {
public:
    int mod=1000000007;

    int sumSubarrayMins(vector<int>& arr) {
        long long int res=0;
        /*for(int i=0;i<arr.size();i++){
            int temp=arr[i];
            for(int j=i;j<arr.size();j++){
                temp=min(temp,arr[j]);
                //cout<<temp<<" ";
                res=(res+temp)%1000000007;
            }
            cout<<endl;
        }*/
        vector<int>left(arr.size(),-1);
        vector<int>right(arr.size(),arr.size());
        stack<int>st;
        for(int i=0;i<arr.size();i++){
            while(!st.empty()&&arr[st.top()]>=arr[i])
                st.pop();
            if(!st.empty())
                left[i]=st.top();
            st.push(i);
        }
        while(!st.empty())
            st.pop();
        for(int i=arr.size()-1;i>=0;i--){
            while(!st.empty()&&arr[st.top()]>arr[i])
                st.pop();
            if(!st.empty())
                right[i]=st.top();
            st.push(i);
        }
        for(int i=0;i<arr.size();i++){
            res=(res+(long)arr[i]*(i-left[i])*(right[i]-i))%mod;
        }
        return res%mod;
    }
};

标签:arr,907,int,st,最小值,数组,empty,size
From: https://www.cnblogs.com/SkyDusty/p/16835676.html

相关文章