Skip to content
Related Articles
Get the best out of our app
GFG App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Median of sliding window in an array | Set 2

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

Prerequisites: Policy based data structure, Sliding window technique.
Given an array of integer arr[] and an integer K, the task is to find the median of each window of size K starting from the left and moving towards the right by one position each time.
Examples: 

Input: arr[] = {-1, 5, 13, 8, 2, 3, 3, 1}, K = 3 
Output: 5 8 8 3 3 3 
Explanation: 
1st Window: {-1, 5, 13} Median = 5 
2nd Window: {5, 13, 8} Median = 8 
3rd Window: {13, 8, 2} Median = 8 
4th Window: {8, 2, 3} Median = 3 
5th Window: {2, 3, 3} Median = 3 
6th Window: {3, 3, 1} Median = 3
Input: arr[] = {-1, 5, 13, 8, 2, 3, 3, 1}, K = 4 
Output: 6.5 6.5 5.5 3.0 2.5 

Naive Approach: 

The simplest approach to solve the problem is to traverse over every window of size K and sort the elements of the window and find the middle element. Print the middle element of every window as the median. 

Steps that were to follow the above approach:

  • Start by defining a function named findMedian which takes three parameters.
    • An integer array arr
    • An integer n which represents the size of array arr
    • An integer k which represents the size of the window     
  • Traverse every window of size k using a for loop that starts at 0 and ends at n-k.
  • For each window, create a temporary array of size k to store elements of the current window.
  • Traverse the current window and copy its elements into the temporary array.
  • Sort the temporary array in ascending order.
  • If k is odd, print the k/2-th element of the sorted temporary array as the median.
  • If k is even, calculate the median by taking the average of the k/2-th and (k+1)/2-1-th elements of the sorted temporary array.
  • Print the median element of each window.
  • In the main function:
    • Define an integer array arr, initialize it with some values.
    • Define an integer n which represents the size of array arr.
    • Define an integer k which represents the size of the window.
    • Call the findMedian function and pass it the array arr, n, and k as arguments.

Below is the code to implement the above approach:

C++




// C++ program to find median of every window of size k in
// an array
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find and return the
// median of every window of size k
void findMedian(int arr[], int n, int k)
{
    // Traverse every window of size k
    for (int i = 0; i <= n - k; i++) {
        // Create a temporary array to store elements of the
        // current window
        int temp[k];
 
        for (int j = 0; j < k; j++)
            temp[j] = arr[i + j];
 
        // Sort the temporary array
        sort(temp, temp + k);
 
        // Print the median element
        // if k is odd, print k/2 th element
        if (k & 1)
            cout << temp[k / 2] << " ";
        else // if k is even take average of k/2th and (k +
             // 1) / 2 - 1th element
            cout << fixed << setprecision(2)
                 << ((float)temp[k / 2]
                     + (float)temp[(k + 1) / 2 - 1])
                        / 2
                 << " ";
    }
}
 
// Driver code
int main()
{
    // input array
    int arr[] = { -1, 5, 13, 8, 2, 3, 3, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 3;
 
    // Function Call
    findMedian(arr, n, k);
    return 0;
}


Java




// Java program to find median of every window of size k in
// an array
 
import java.util.*;
 
class GFG {
    // Function to find and return the median of every window of size k
    static void findMedian(int[] arr, int n, int k) {
        // Traverse every window of size k
        for (int i = 0; i <= n - k; i++) {
            // Create a temporary array to store elements of the current window
            int[] temp = new int[k];
 
            for (int j = 0; j < k; j++)
                temp[j] = arr[i + j];
 
            // Sort the temporary array
            Arrays.sort(temp);
 
            // Print the median element
            // if k is odd, print k/2 th element
            if (k % 2 == 1)
                System.out.print(temp[k / 2] + " ");
            else // if k is even take average of k/2th and (k + 1) / 2 - 1th element
                System.out.print(((float)temp[k / 2] + (float)temp[(k + 1) / 2 - 1]) / 2 + " ");
        }
    }
 
    // Driver code
    public static void main(String[] args) {
        // input array
        int[] arr = { -1, 5, 13, 8, 2, 3, 3, 1 };
        int n = arr.length;
        int k = 3;
 
        // Function Call
        findMedian(arr, n, k);
    }
}


Python3




# Python3 program to find median of every window of size k in
# an array
 
import statistics
 
# Function to find and return the
# median of every window of size k
def findMedian(arr, n, k):
    # Traverse every window of size k
    for i in range(n - k + 1):
      # Create a temporary array to store elements of the
      # current window
      temp = arr[i:i+k]
       
      # Print the median element
      # if k is odd, print k/2 th element
      if k & 1:
          print(statistics.median(temp), end=" ")
      else: # if k is even take average of k/2th and (k + 1) / 2 - 1th element
          median = (statistics.median_high(temp) + statistics.median_low(temp)) / 2
          print("{:.2f}".format(median), end=" ")
 
# Driver code
if __name__ == "__main__":
  # input array
  arr = [-1, 5, 13, 8, 2, 3, 3, 1]
  n = len(arr)
  k = 3
   
  # Function Call
  findMedian(arr, n, k)


Output

5 8 8 3 3 3 

Time Complexity: O(N*KlogK) 
Auxiliary Space: O(K)
Sorted Set Approach: Refer to Median of sliding window in an array to solve the problem using SortedSet.
Ordered Set Approach: 
In this article, an approach to solving the problem using a Policy-based Ordered set data structure. 
Follow the steps below to solve the problem: 

  • Insert the first window of size K in the Ordered_set( maintains a sorted order). Hence, the middle element of this Ordered set is the required median of the corresponding window. 
     
  • The middle element can be obtained by the find_by_order() method in O(logN) computational complexity.
  • Proceed to the following windows by remove the first element of the previous window and insert the new element. To remove any element from the set, find the order of the element in the Ordered_Set using order_by_key(), which fetches the result in O(logN) computational complexity, and erase() that element by searching its obtained order in the Ordered_Set using find_by_order() method. Now add the new element for the new window.  
  • Repeat the above steps for each window and print the respective medians.  

Below is the implementation of the above approach.

CPP




// C++ Program to implement the
// above approach
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
 
using namespace std;
using namespace __gnu_pbds;
 
// Policy based data structure
typedef tree<int, null_type,
             less_equal<int>, rb_tree_tag,
             tree_order_statistics_node_update>
    Ordered_set;
 
// Function to find and return the
// median of every window of size k
void findMedian(int arr[], int n,
                int k)
{
 
    Ordered_set s;
 
    for (int i = 0; i < k; i++)
        s.insert(arr[i]);
 
    if (k & 1) {
 
        // Value at index k/2
        // in sorted list.
        int ans = *s.find_by_order(k / 2);
 
        cout << ans << " ";
 
        for (int i = 0; i < n - k; i++) {
 
            // Erasing Element out of window.
            s.erase(s.find_by_order(
                s.order_of_key(
                    arr[i])));
 
            // Inserting newer element
            // to the window
            s.insert(arr[i + k]);
 
            // Value at index k/2 in
            // sorted list.
            ans = *s.find_by_order(k / 2);
 
            cout << ans << " ";
        }
        cout << endl;
    }
    else {
 
        // Getting the two middle
        // median of sorted list.
        float ans = ((float)*s.find_by_order(
                         (k + 1) / 2 - 1)
                     + (float)*s.find_by_order(k
                                               / 2))
                    / 2;
 
        printf("%.2f ", ans);
 
        for (int i = 0; i < n - k; i++) {
            s.erase(s.find_by_order(
                s.order_of_key(arr[i])));
 
            s.insert(arr[i + k]);
 
            ans = ((float)*s.find_by_order(
                       (k + 1) / 2 - 1)
                   + (float)*s.find_by_order(k
                                             / 2))
                  / 2;
 
            printf("%.2f ", ans);
        }
        cout << endl;
    }
}
 
// Driver Code
int main()
{
    int arr[] = { -1, 5, 13, 8, 2,
                  3, 3, 1 };
    int k = 3;
 
    int n = sizeof(arr)
            / sizeof(arr[0]);
    findMedian(arr, n, k);
 
    return 0;
}


Java




import java.util.Scanner;
import java.util.TreeSet;
 
public class GFG {
 
    // Function to find and return the median of every window of size k
    public static void findMedian(int[] arr, int n, int k) {
 
        TreeSet<Integer> s = new TreeSet<>();
 
        for (int i = 0; i < k; i++) {
            s.add(arr[i]);
        }
 
        if (k % 2 == 1) {
            // Value at index k/2 in sorted list.
            int ans = s.toArray(new Integer[0])[k / 2];
 
            System.out.print(ans + " ");
 
            for (int i = 0; i < n - k; i++) {
                // Erasing Element out of window.
                s.remove(arr[i]);
 
                // Inserting newer element to the window
                s.add(arr[i + k]);
 
                // Value at index k/2 in sorted list.
                ans = s.toArray(new Integer[0])[k / 2];
 
                System.out.print(ans + " ");
            }
            System.out.println();
        } else {
            // Getting the two middle median of sorted list.
            float ans = ((float)s.toArray(new Integer[0])[(k + 1) / 2 - 1]
                    + (float)s.toArray(new Integer[0])[k / 2]) / 2;
 
            System.out.printf("%.2f ", ans);
 
            for (int i = 0; i < n - k; i++) {
                s.remove(arr[i]);
                s.add(arr[i + k]);
 
                ans = ((float)s.toArray(new Integer[0])[(k + 1) / 2 - 1]
                        + (float)s.toArray(new Integer[0])[k / 2]) / 2;
 
                System.out.printf("%.2f ", ans);
            }
            System.out.println();
        }
    }
 
    // Driver Code
    public static void main(String[] args) {
 
        int[] arr = {-1, 5, 13, 8, 2, 3, 3, 1};
        int k = 3;
 
        int n = arr.length;
        findMedian(arr, n, k);
    }
}
// This code is contributed by Shivam Tiwari


Python3




# Python program to implement the
# above approach
 
# Policy based data structure
# in Python (using sortedcontainers package)
from sortedcontainers import SortedList
 
def findMedian(arr, n, k):
 
    s = SortedList()
 
    for i in range(k):
        s.add(arr[i])
 
    if k & 1:
 
        # Value at index k/2 in sorted list.
        ans = s[k//2]
 
        print(ans, end=' ')
 
        for i in range(n-k):
 
            # Erasing Element out of window.
            s.remove(arr[i])
 
            # Inserting newer element to the window
            s.add(arr[i+k])
 
            # Value at index k/2 in sorted list.
            ans = s[k//2]
 
            print(ans, end=' ')
        print()
    else:
 
        # Getting the two middle median of sorted list.
        ans = (s[(k+1)//2-1] + s[k//2]) / 2.0
 
        print("%.2f" % ans, end=' ')
 
        for i in range(n-k):
            s.remove(arr[i])
 
            s.add(arr[i+k])
 
            ans = (s[(k+1)//2-1] + s[k//2]) / 2.0
 
            print("%.2f" % ans, end=' ')
        print()
 
# Driver Code
if __name__ == '__main__':
    arr = [-1, 5, 13, 8, 2, 3, 3, 1]
    k = 3
 
    n = len(arr)
    findMedian(arr, n, k)


Javascript




function findMedian(arr, n, k) {
    // Create a TreeSet to store the current window of elements
    let s = new Set();
 
    // Add the first k elements to the TreeSet
    for (let i = 0; i < k; i++) {
        s.add(arr[i]);
    }
 
    if (k % 2 == 1) {
        // If k is odd, the median is the value at index k/2 in the sorted list
        let ans = Array.from(s)[(Math.floor(k / 2))];
 
        process.stdout.write(`${ans} `);
 
        for (let i = 0; i < n - k; i++) {
            // Remove the element that's no longer in the window
            s.delete(arr[i]);
 
            // Add the next element to the window
            s.add(arr[i + k]);
 
            // Calculate the new median
            ans = Array.from(s)[(Math.floor(k / 2))];
 
            process.stdout.write(`${ans} `);
        }
        console.log();
    } else {
        // If k is even, the median is the average of the two middle elements in the sorted list
        let ans = (Array.from(s)[(k + 1) / 2 - 1] + Array.from(s)[k / 2]) / 2;
 
        process.stdout.write(`${ans.toFixed(2)} `);
 
        for (let i = 0; i < n - k; i++) {
            s.delete(arr[i]);
            s.add(arr[i + k]);
 
            ans = (Array.from(s)[(k + 1) / 2 - 1] + Array.from(s)[k / 2]) / 2;
 
            process.stdout.write(`${ans.toFixed(2)} `);
        }
        console.log();
    }
}
 
// Driver Code
let arr = [-1, 5, 13, 8, 2, 3, 3, 1];
let k = 3;
let n = arr.length;
findMedian(arr, n, k);
// This code is contributed by Shivam Tiwari


C#




using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.IO;
 
    class GFG
    {
        // Function to find and return the median of every window of size k
        static void FindMedian(int[] arr, int n, int k)
        {
            SortedSet<int> set = new SortedSet<int>();
 
            for (int i = 0; i < k; i++)
                set.Add(arr[i]);
 
            if (k % 2 != 0)
            {
                // Value at index k/2
                // in sorted list.
                int ans = set.ElementAt((k / 2));
 
                Console.Write(ans + " ");
 
                for (int i = 0; i < n - k; i++)
                {
 
                    // Erasing Element out of window.
                    set.Remove(arr[i]);
 
                    // Inserting newer element
                    // to the window
                    set.Add(arr[i + k]);
 
                    // Value at index k/2 in
                    // sorted list.
                    ans = set.ElementAt((k / 2));
 
                    Console.Write(ans + " ");
                }
 
                Console.WriteLine();
            }
            else
            {
 
                // Getting the two middle
                // median of sorted list.
                double ans = ((double)set.ElementAt((k + 1) / 2 - 1) +
                            (double)set.ElementAt(k / 2)) / 2;
 
                Console.Write(Math.Round(ans, 2) + " ");
 
                for (int i = 0; i < n - k; i++)
                {
                    set.Remove(arr[i]);
 
                    set.Add(arr[i + k]);
 
                    ans = ((double)set.ElementAt((k + 1) / 2 - 1) +
                            (double)set.ElementAt(k / 2)) / 2;
 
                    Console.Write(Math.Round(ans, 2) + " ");
                }
 
                Console.WriteLine();
            }
        }
 
        // Driver code
        static void Main(string[] args)
        {
            int[] arr = { -1, 5, 13, 8, 2, 3, 3, 1 };
            int k = 3;
 
            int n = arr.Length;
            FindMedian(arr, n, k);
        }
    }
// This code is contributed By Shivam Tiwari


Output

5 8 8 3 3 3 

Time Complexity: O(NlogK) 
Auxiliary Space: O(K)
 


My Personal Notes arrow_drop_up
Last Updated : 14 Apr, 2023
Like Article
Save Article
Similar Reads
Related Tutorials