907. Sum of Subarray Minimums

class Solution {
    public int sumSubarrayMins(int[] arr) {
        // for every num in arr
        // find the index of the previous less num (j), and the index of the next less num (k)
        // result =sum(num*(i-j)*(k-i));
        // if there is equal, alwasy consider the num with samller (larger) index contribute to the min, meaning the stack generate previous less num will in stick mode, but the one generate next less num does not
        
        // pushes index of array to it
        Stack<Integer> s1 = new Stack<>();
        int[] left = new int[arr.length];
        for(int i=0; i<arr.length; i++){
            while(!s1.isEmpty() && arr[s1.peek()]>=arr[i]){
                s1.pop();
            }
            left[i]=s1.isEmpty() ? -1 : s1.peek();
            s1.push(i);
        }
        // get next small element, not 
        Stack<Integer> s2 = new Stack<>();
        int[] right = new int[arr.length];
        for(int i=arr.length-1; i>=0; i--){
            while(!s2.isEmpty() && arr[s2.peek()]>arr[i]){
                s2.pop();
            }
            right[i]=s2.isEmpty() ? arr.length : s2.peek();
            s2.push(i);
        }
        
        double result = 0;
        double mod = (Math.pow(10,9)+7);
        for(int i=0; i<arr.length; i++){
            result=(result + (double)arr[i]*(i-left[i])*(right[i]-i))%mod;
        }
        return (int)result;
    }
}

Last updated