You are given an array nums
of size n
consisting of distinct integers from 1
to n
and a positive integer k
.
Return the number of non-empty subarrays in nums
that have a median equal to k
.
Note:
[2,3,1,4]
is 2
, and the median of [8,4,3,5,1]
is 4
.Example 1:
Input: nums = [3,2,1,4,5], k = 4 Output: 3 Explanation: The subarrays that have a median equal to 4 are: [4], [4,5] and [1,4,5].
Example 2:
Input: nums = [2,3,1], k = 3 Output: 1 Explanation: [3] is the only subarray that has a median equal to 3.
Constraints:
n == nums.length
1 <= n <= 105
1 <= nums[i], k <= n
nums
are distinct.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:
The brute force strategy is to look at every single possible continuous group of numbers within the main list. For each of these groups, we'll figure out what its middle number is and check if it's the special number 'K' we're looking for.
Here's how the algorithm would work step-by-step:
def count_subarrays_with_median_k(numbers, special_k_value):
subarray_count = 0
list_length = len(numbers)
# The first loop defines the starting point of our continuous group (subarray).
for start_index in range(list_length):
# The second loop defines the ending point, thus creating all possible subarrays.
for end_index in range(start_index, list_length):
current_subarray = numbers[start_index:end_index + 1]
# For each subarray, we must sort it to find the middle element, which is the median.
sorted_subarray = sorted(current_subarray)
subarray_length = len(sorted_subarray)
# The median index depends on whether the subarray length is odd or even.
median_index = (subarray_length - 1) // 2
median_value = sorted_subarray[median_index]
if median_value == special_k_value:
subarray_count += 1
return subarray_count
The core idea is to re-imagine the numbers in the list based on their relationship to the target number, K. This simplifies the problem into finding groups of numbers where the count of larger numbers either equals or is one more than the count of smaller numbers, which is a much easier problem to solve.
Here's how the algorithm would work step-by-step:
from collections import defaultdict
def count_subarrays_with_median_k(numbers, k):
# Step 1: Find the index of k. Any valid subarray must contain this element.
try:
k_index = numbers.index(k)
except ValueError:
return 0
# Step 5: Calculate prefix sums for the left part of the array relative to k.
left_balance_counts = defaultdict(int)
left_balance_counts[0] = 1
current_balance = 0
for index in range(k_index - 1, -1, -1):
if numbers[index] < k:
current_balance -= 1
else:
current_balance += 1
left_balance_counts[current_balance] += 1
total_valid_subarrays = 0
current_balance = 0
# The subarray containing just k is a valid starting point.
total_valid_subarrays += left_balance_counts[0] + left_balance_counts[1]
# Step 6 & 7: Iterate rightward from k, calculating balance and pairing with left balances.
for index in range(k_index + 1, len(numbers)):
if numbers[index] < k:
current_balance -= 1
else:
current_balance += 1
# A balance of 0 or 1 makes k the median. We need the opposite balance from the left part.
# To get a total balance of 0, we need -current_balance from the left.
total_valid_subarrays += left_balance_counts[-current_balance]
# To get a total balance of 1, we need 1-current_balance from the left.
total_valid_subarrays += left_balance_counts[1 - current_balance]
return total_valid_subarrays
Case | How to Handle |
---|---|
Input array is empty or null | The solution should return 0 as no subarrays can be formed. |
The integer k does not exist in the input array | No subarray can have k as its median, so the function must return 0. |
Input array has only one element | The solution correctly counts 1 if the single element is k, and 0 otherwise. |
All elements in the array are equal to k | Every possible subarray will have k as its median, so the solution should correctly count all n*(n+1)/2 subarrays. |
The integer k is the smallest or largest value in the array | The relative balance logic correctly handles cases where elements are only greater than or only less than k. |
Input array contains negative numbers and zeros | The solution is robust as it only cares about the relative values of elements compared to k, not their absolute values. |
Large input array size (e.g., up to 10^5 elements) | An O(N) solution using prefix sums and a hash map is required to avoid a timeout from a brute-force O(N^2) approach. |
Array contains multiple instances of k | The solution must correctly calculate subarrays centered around each occurrence of k, which the prefix sum approach naturally handles. |