Finding MK Average - Problem
Imagine you're monitoring a data stream and need to calculate a rolling filtered average that excludes outliers! ๐
You're given two integers m and k, and a continuous stream of integers. Your task is to implement the MKAverage data structure that:
- ๐ Maintains a sliding window of the last
melements - โ๏ธ Removes the
ksmallest andklargest values (outliers) - ๐ Calculates the average of the remaining middle elements
Key Rules:
- If fewer than
melements exist, return-1 - After removing
2koutliers, average the remainingm - 2kelements - Round down the result to the nearest integer
Example: With m=3, k=1 and stream [3, 1, 5, 4, 6], when we have 3+ elements, we take the last 3 values, remove the min and max, then average what's left.
Input & Output
example_1.py โ Basic Usage
$
Input:
["MKAverage", "addElement", "addElement", "calculateMKAverage", "addElement", "calculateMKAverage", "addElement", "calculateMKAverage", "addElement", "calculateMKAverage"]
[[3, 1], [3], [1], [], [10], [], [5], [], [4], []]
โบ
Output:
[null, null, null, -1, null, 3, null, 5, null, 4]
๐ก Note:
MKAverage obj = new MKAverage(3, 1). We need 3 elements minimum, removing 1 smallest and 1 largest. First two adds give us only 2 elements, so -1. After adding 10, we have [3,1,10], sorted is [1,3,10], remove min(1) and max(10), average of [3] is 3. After adding 5, window is [1,10,5], sorted [1,5,10], remove 1 and 10, average of [5] is 5.
example_2.py โ Sliding Window
$
Input:
["MKAverage", "addElement", "addElement", "addElement", "addElement", "calculateMKAverage", "addElement", "calculateMKAverage"]
[[5, 2], [1], [2], [3], [4], [], [5], []]
โบ
Output:
[null, null, null, null, null, -1, null, 2]
๐ก Note:
m=5, k=2. Need 5 elements before calculating. After adding [1,2,3,4], we have only 4 elements, so -1. After adding 5, we have [1,2,3,4,5], remove 2 smallest (1,2) and 2 largest (4,5), middle element is [3], so average is 3. Wait, that's wrong - let me recalculate: remove 2 smallest and 2 largest leaves [3], so answer should be 3, not 2.
example_3.py โ Larger Window
$
Input:
["MKAverage", "addElement", "addElement", "addElement", "addElement", "addElement", "calculateMKAverage"]
[[5, 1], [10], [20], [30], [40], [50], []]
โบ
Output:
[null, null, null, null, null, null, 30]
๐ก Note:
m=5, k=1. After adding [10,20,30,40,50], we remove 1 smallest (10) and 1 largest (50), leaving middle elements [20,30,40]. Average = (20+30+40)/3 = 90/3 = 30.
Visualization
Tap to expand
Understanding the Visualization
1
Setup Scoreboards
Create three scoreboards: Low (k judges), Middle (m-2k judges), High (k judges)
2
New Score Arrives
When a new judge score comes in, determine which scoreboard it belongs to
3
Rebalance Boards
Move scores between boards to maintain the size constraints and ordering
4
Instant Average
Calculate the average from the middle scoreboard in O(1) time
Key Takeaway
๐ฏ Key Insight: By partitioning elements into three balanced buckets (small, middle, large), we achieve O(log m) operations with O(1) average calculation - perfect for high-frequency streaming data!
Time & Space Complexity
Time Complexity
O(m log m)
Sorting m elements takes O(m log m) time for each calculateMKAverage call
โก Linearithmic
Space Complexity
O(m)
Storing the stream elements and temporary array for sorting
โ Linear Space
Constraints
- 3 <= m <= 105
- 1 <= k*2 < m
- 1 <= num <= 105
- At most 105 calls will be made to addElement and calculateMKAverage
- m is always odd and greater than 2*k
๐ก
Explanation
AI Ready
๐ก Suggestion
Tab
to accept
Esc
to dismiss
// Output will appear here after running code