Given an integer array nums
and two integers left
and right
, return the number of contiguous non-empty subarrays such that the value of the maximum array element in that subarray is in the range [left, right]
.
The test cases are generated so that the answer will fit in a 32-bit integer.
Example 1:
Input: nums = [2,1,4,3], left = 2, right = 3 Output: 3 Explanation: There are three subarrays that meet the requirements: [2], [2, 1], [3].
Example 2:
Input: nums = [2,9,2,5,6], left = 2, right = 8 Output: 7
Constraints:
1 <= nums.length <= 105
0 <= nums[i] <= 109
0 <= left <= right <= 109
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
We want to find all the small groups of numbers from a larger list that meet specific criteria. The brute force method simply looks at every possible small group and checks if it fits.
Here's how the algorithm would work step-by-step:
def count_subarrays_brute_force(numbers, left_bound, right_bound):
subarray_count = 0
list_length = len(numbers)
for subarray_length in range(1, list_length + 1):
# Iterate through all possible subarray starting positions
for start_index in range(list_length - subarray_length + 1):
subarray_maximum = -float('inf')
# Find the maximum element within the current subarray.
for index in range(start_index, start_index + subarray_length):
subarray_maximum = max(subarray_maximum, numbers[index])
# Check if the maximum is within the specified bounds.
if left_bound <= subarray_maximum <= right_bound:
subarray_count += 1
return subarray_count
The best approach focuses on counting valid sections directly. We'll keep track of the ending positions of valid sections and efficiently add them together to get the total count, avoiding unnecessary re-calculations.
Here's how the algorithm would work step-by-step:
def number_of_subarrays_with_bounded_maximum(nums, left_bound, right_bound):
last_too_small_position = -1
last_too_large_position = -1
current_subarray_count = 0
total_subarray_count = 0
for index, number in enumerate(nums):
if number < left_bound:
last_too_small_position = index
if number > right_bound:
# Reset because it breaks all previous sections
last_too_large_position = index
current_subarray_count = 0
# Valid number, count subarrays ending here.
elif left_bound <= number <= right_bound:
current_subarray_count = index - last_too_small_position
total_subarray_count += current_subarray_count
return total_subarray_count
Case | How to Handle |
---|---|
Empty array input | Return 0 immediately as there are no subarrays. |
Array with one element | Check if the single element is within the bounds (left <= element <= right) and return 1 or 0 accordingly. |
All elements in the array are less than the left bound | Return 0 as no subarray will satisfy the condition. |
All elements in the array are greater than the right bound | Return 0 as no subarray will satisfy the condition. |
All elements in the array are within the bounds (left <= element <= right) | Return n * (n + 1) / 2, where n is the length of the array, because all subarrays are valid. |
Array contains negative numbers, zeros and positive numbers | The solution should handle negative and zero values correctly as it only checks if an element is within the given bounds. |
Large array size causing potential integer overflow | Use long data type for calculations involving the number of subarrays to avoid potential overflow issues. |
Left bound equals Right bound | The solution should correctly identify subarrays where the maximum value equals the bound value. |