LeetCode-in-Java

3748. Count Stable Subarrays

Hard

You are given an integer array nums.

A non-empty subarrays of nums is called stable if it contains no inversions, i.e., there is no pair of indices i < j such that nums[i] > nums[j].

You are also given a 2D integer array queries of length q, where each queries[i] = [li, ri] represents a query. For each query [li, ri], compute the number of stable subarrays that lie entirely within the segment nums[li..ri].

Return an integer array ans of length q, where ans[i] is the answer to the ith query.

Note:

Example 1:

Input: nums = [3,1,2], queries = [[0,1],[1,2],[0,2]]

Output: [2,3,4]

Explanation:

Thus, ans = [2, 3, 4].

Example 2:

Input: nums = [2,2], queries = [[0,1],[0,0]]

Output: [3,1]

Explanation:

Thus, ans = [3, 1].

Constraints:

Solution

public class Solution {
    public long[] countStableSubarrays(int[] nums, int[][] queries) {
        int n = nums.length;
        long[] preSum = new long[n + 1];
        int[] idx = new int[n];
        int[] end = new int[n];
        int cnt = 0;
        int prv = -1;
        for (int i = 0; i < n; i++) {
            if (nums[i] >= prv) {
                cnt++;
            } else {
                cnt = 1;
            }
            prv = nums[i];
            preSum[i + 1] = preSum[i] + cnt;
            idx[i] = cnt - 1;
        }
        end[n - 1] = n - 1;
        for (int i = n - 2; i >= 0; i--) {
            if (idx[i] + 1 == idx[i + 1]) {
                end[i] = end[i + 1];
            } else {
                end[i] = i;
            }
        }
        long[] ans = new long[queries.length];
        for (int l = 0; l < queries.length; l++) {
            int i = queries[l][0];
            int j = queries[l][1];
            long res = preSum[j + 1] - preSum[i];
            int endIdx = Math.min(end[i], j);
            res -= (long) (endIdx - i + 1) * idx[i];
            ans[l] = res;
        }
        return ans;
    }
}