leetcode 907. 子数组的最小值之和()

版权声明:本文为博主原创文章,转载请在下面留个言就好 https://blog.csdn.net/Dylan_Frank/article/details/83099461

题目链接

907. 子数组的最小值之和

分析

直接DP就好了,求两个数组: left,right,分别表示

left[i] :比i小的左端点,(注意,为避免相等时重复统计,计左不计右)

code

class Solution {
	
	private static final int MOD = 1000000007;
	private void debug(int [] pri) {
		for(int i=0,n = pri.length; i< n ; i++)System.out.print(pri[i]+" ");
		System.out.println();
	}
	public int sumSubarrayMins(int[] A) {
		int n = A.length;
		int[] left = new int[n];
		int[] right = new int[n];
		left[0] =-1;
		for(int i=1 ; i<n ; ++i){
			if(A[i-1] <= A[i])left[i] = i-1;
			else{
				int now = i-1;
				while (now !=-1 &&A[now] > A[i] ) {//算左不算右,避免重复统计
					now = left[now];
				}
				left[i] = now;
			}
		}
		right[n -1] = n;
		for(int i=n -2 ; i >=0 ; --i){
			if(A[i+1]< A[i])right[i] = i+1;
			else{
				int now = i+1;
				while (now != n && A[now] >= A[i]) {
					now = right[now];
				}
				right[i] = now;
			}
		}
//		debug(left);
//		debug(right);
		long ans = 0;
		for(int i=0 ; i<n ; ++i){
			ans += (long)A[i]*(right[i] - i)*(i - left[i]);
			ans %=MOD;
		}
		return (int)ans;
    }
}

猜你喜欢

转载自blog.csdn.net/Dylan_Frank/article/details/83099461