Problem Description
Given an integer array nums and an integer k, each subarray can have at most k operations applied where one may increment any element by 1 per operation. For each subarray (considered independently), determine if one can transform it into a non-decreasing sequence by performing at most k operations. Return the count of subarrays for which this is possible.
A subarray is non-decreasing if for every adjacent pair the later element is greater than or equal to the previous element.
Key Insights
- The minimum number of operations needed to “fix” a subarray is found by simulating the greedy process: start from the first element and ensure each subsequent element is at least the current maximum; if not, increment it. Thus, the cost for subarray nums[l...r] equals ∑₍ᵢ₌ₗ₊₁₎^r (max_{j=l..i-1} – nums[i]) (only when this difference is positive).
- For any fixed starting index l, as we extend r the cost is non-decreasing (each new element only adds a non-negative cost).
- If we let current = nums[l] and process the subarray, then when a new element is encountered: • If it is less than current, the cost increases by (current – nums[i]). • Otherwise, current is updated to nums[i] (and no extra cost is added).
- One can “decompose” the subarray into segments where the maximum (thus the “target” value) is constant. In such a segment, the cost is computed as: segment_cost = (segment_length × value) – (sum of the values in that segment).
- Precomputing the next-greater element for each index enables a segmentation of the subarray and helps compute cost quickly. In addition, constructing prefix sums allows us to calculate the cost over any segment in O(1) time.
- Then, for every starting index l, we can use binary search (or a two‐pointer style “expanding window” that jumps over segments) to find the maximum valid r where the cost is ≤ k.
- Finally, by summing over all l the number of valid subarrays that start at l, we obtain the answer.
Space and Time Complexity
Time Complexity: O(n log n) in the worst case. For each starting index, binary search is used to locate the maximum r. (A careful “two‐pointers” solution might achieve O(n) overall but requires sophisticated maintenance.) Space Complexity: O(n) for the prefix sums, next-greater indices array, and any auxiliary data structures.
Solution
We first note that for a subarray nums[l...r] the minimal cost to make it non‐decreasing is achieved by “fixing” it in one pass: starting with current = nums[l], for each index i from l+1 to r, if nums[i] is smaller than current then we would spend (current – nums[i]) operations and otherwise update current. This sum is our “cost” for that subarray.
One idea is to precompute for every index its “next greater index” (i.e. the first index to the right having a strictly larger value). This divides the subarray starting at l into segments where the maximum remains constant. Specifically, if for a starting index l the first segment runs up to index r₁ (where r₁ is the next greater position than l or the end of the array), then for every i in [l+1, r₁-1] the “target” value is nums[l]. The cost over this segment is: nums[l] × (segment_length) – (sum of values in that segment).
If r extends into the next segment, the target is updated and the cost is computed similarly on the next segment. By precomputing prefix sums of nums the cost over any segment can be computed quickly.
For each starting index l, we then binary search over r (or move a pointer by segments) while accumulating the cost. The subarray is valid if the total cost does not exceed k. Finally, the answer is the total count of all valid subarrays.
The trick is in efficiently “querying” the cost for a given r from l. With the next-greater structure and prefix sums, we can compute the cost piecewise without scanning every element in the subarray.
A detailed implementation will:
- Precompute prefix sums.
- Precompute next greater elements for every index.
- For each starting index l, simulate the segmentation of the subarray by “jumping” segments and use binary search (or a while-loop with careful bounds) to determine the largest r such that cost(l, r) ≤ k.
- Sum over all l the number of valid subarrays starting at l.
Code Solutions
Below are implementations in Python, JavaScript, C++, and Java. Each solution includes line‐by‐line comments.