package arithmetic.minmax;
import java.util.Arrays;
import java.util.Stack;
/**
*
* 已知数组int[]numbers,
* 求这个数组任意区间内最小的值与区间和的乘积的最大值,例:numbers=[5,4,3],
* 区间[5,4]的乘积=4*9=36,[4,3]=21,[5,4,3]=3*12=36, 以此类推最大值=36,
*
*/
public class MinMax<N> {
//单调栈,时间复杂度O(N)
public void test () {
int[] a = {1,2,3,4,5};
int n = 5;
int[] dp = new int[50];
Stack<Integer> s=new Stack<>();
int res = 0;
//前缀和便于快速求区间和,例如求[l,r]区间和=dp[r+1]-dp[l]。l和r的取值范围是[0,n)
for( int i = 1;i <=n;i++ ) {
dp[i] = dp[i-1]+a[i-1];
}
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(dp));
for (int i = 0; i < n; i++) {
while (!s.empty() && a[i] <= a[s.peek()]) {
int peak = a[s.peek()];
s.pop();
int l = s.empty()?-1:s.peek();
int r = i;
//l和r是边界,因此区间是[l+1,r-1],其区间和dp[r+1]-dp[l]
int dist = dp[r]-dp[l+1];
res = max(res,peak*dist);
System.out.println("1---"+res);
}
s.push(i);
System.out.println("2---"+res+"--"+i);
}
while (!s.empty()) {
int peak = a[s.peek()];
s.pop();
int l = s.empty()?-1:s.peek();
int r=n;
int dist = dp[r]-dp[l+1];
res = max(res,peak*dist);
System.out.println("3---"+res);
}
System.out.println("4---"+res);
System.out.println(res);
}
int max(int a,int b ) {
if (a >= b) {
return a;
}else {
return b;
}
}
public static void main(String[] args) {
new MinMax().test () ;
}
}