2
https://leetcode.com/problems/sliding-window-median/4
1. SOLUTION 1: Binary Search6
The core idea is we maintain a sorted window of elements. Initially we make7
the 1st window and sort all its elements. Then from there onwards any8
insertion or deletion is done by first finding the appropriate position where9
the element exists/shoudl exist. This search is done using binary search.11
TC: O(klogk (Sorting) + (n - k) * (k + logk)), Binary search in window takes12
O(logk), but since it is array, insert or delete can take O(k) SC: O(k)14
2. SOLUTION 2: Height Balanced Tree16
Core idea is to use a height balanced tree to save all the elements of17
window. Since it is a height balanced tree, insertion and deletion takes18
logk. Now we directly want to reach the k/2 th element, then it takes19
O(k/2). So we need to optimize the mid point fetch.21
Initially when the 1st window is built, we find the middle element with22
O(k/2). Then from there onwards we always adjust the middle position by +1 or23
-1. Since only one element is either added or deleted at a time, so we can24
move the median left or right based on the situation. Eg: [1,2,3,4,5,6,7],27
if we add one element say 928
[1,2,3,4,5,6,7,9], then check (9 < median): this means 1 extra element on29
right, don't move and wait to see what happens on deletion31
Similarly, now if 2 is deleted, we can just check (2 <= median(4)): this32
means there will be one less element on left. So move median to right by 1.33
If say an element on right like 7 was deleted, we would have not moved and34
hence the mid ptr would be at its correct position.37
(1st window insertion) + remaining_windows * (delete element + add38
element + get middle) TC: O(klogk + (n-k) * (logk + logk + 1)) ~O(klogk +39
(n-k)*logk) ~O(nlogk) SC: O(k)43
///////////////////// SOLUTION 1: Binary Search44
vector<double> binarySearchSol(vector<int> &nums, int k) {45
vector<double> medians;47
// K is over the size of array48
if (k > nums.size()) return medians;51
// add the elements of 1st window53
window.emplace_back(nums[i]);58
sort(window.begin(), window.end());59
// get the median of 1st window60
double median = k % 2 ? window[k / 2] : (double)((double)window[k / 2 - 1] + window[k / 2]) / 2;61
medians.emplace_back(median);63
for (; i < nums.size(); i++) {64
// search the position of 1st element of the last window using binary66
auto it = lower_bound(window.begin(), window.end(), nums[i - k]);68
// find the position to insert the new element for the current window69
it = lower_bound(window.begin(), window.end(), nums[i]);70
window.insert(it, nums[i]);71
// Since the window is sorted, we can directly compute the median73
k % 2 ? window[k / 2] : (double)((double)window[k / 2 - 1] + window[k / 2]) / 2;74
medians.emplace_back(median);79
//////////////////////////// SOLUTION 2: Height Balanced Tree80
vector<double> treeSol(vector<int> &nums, int k) {81
multiset<int> elements;82
vector<double> medians;85
// process the 1st window87
elements.insert(nums[i]);91
// median of 1st window92
auto mid = next(elements.begin(), k / 2);93
double median = k % 2 ? *mid : ((double)*mid + *prev(mid)) / 2;94
medians.emplace_back(median);96
for (; i < nums.size(); i++) {97
// insert last element of current window98
elements.insert(nums[i]);99
// If the number lies on the left, left side will have 1 more element.100
// So shift left by 1 pos101
if (nums[i] < *mid) --mid;103
// remove 1st element of last window104
auto delete_pos = elements.find(nums[i - k]);105
// If the element to be deleted in [first : mid], then right will have106
// extra element so move the mid to right by 1 NOTE: We insert the new107
// element and then delete previous element because, if the window has108
// just one element then deleting first will make mid point to invalid109
// position. But inserting first will ensure that there is an element to111
if (nums[i - k] <= *mid) ++mid;112
elements.erase(delete_pos);114
double median = k % 2 ? *mid : ((double)*mid + *prev(mid)) / 2;115
medians.emplace_back(median);121
vector<double> medianSlidingWindow(vector<int> &nums, int k) {122
// return binarySearchSol(nums, k);123
return treeSol(nums, k);