Find the sum of medians of all odd length subarrays
Last Updated :
22 Feb, 2023
Given an array arr[] of size N, the task is to find the sum of medians of all sub-array of odd-length.
Examples:
Input: arr[] = {4, 2, 5, 1}
Output: 18
Explanation : Sub-Arrays of odd length and their medians are :
- [4] -> Median is 4
- [4, 2, 5] -> Median is 4
- [2] -> Median is 2
- [2, 5, 1] -> Median is 2
- [5] -> Median is 5
- [1] -> Median is 1
Their sum = 4 + 4+ 2 + 2 + 5 +1 = 18
Input: arr[] = {1, 2}
Output: 3
Pre-requisites: Median of Stream of Running Integers using STL
Naive Approach: Generate each and every sub-array. If the length of the sub-array is odd, then sort the sub-array and return the middle element.
Below is the implementation of the above approach:
C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to find sum of medians
// of all odd-length subarrays
int solve(vector<int> arr)
{
int ans = 0;
int n = arr.size();
// Loop to calculate the sum
for(int i = 0; i < n; i++)
{
vector<int> new_arr;
for(int j = i; j < n; j++)
{
new_arr.push_back(arr[j]);
// Odd length subarray
if ((new_arr.size() % 2) == 1)
{
sort(new_arr.begin(), new_arr.end());
int mid = new_arr.size() / 2;
ans += new_arr[mid];
}
}
}
return ans;
}
// Driver Code
int main()
{
vector<int> arr = { 4, 2, 5, 1 };
cout << solve(arr);
}
// This code is contributed by Samim Hossain Mondal.
Java
// Java program for the above approach
import java.util.*;
class GFG {
// Function to find sum of medians
// of all odd-length subarrays
static int solve(int[] arr) {
int ans = 0;
int n = arr.length;
// Loop to calculate the sum
for (int i = 0; i < n; i++) {
List<Integer> new_arr = new LinkedList<Integer>();
for (int j = i; j < n; j++) {
new_arr.add(arr[j]);
// Odd length subarray
if ((new_arr.size() % 2) == 1) {
Collections.sort(new_arr);
int mid = new_arr.size() / 2;
ans += new_arr.get(mid);
}
}
}
return ans;
}
// Driver Code
public static void main(String[] args) {
int[] arr = { 4, 2, 5, 1 };
System.out.println(solve(arr));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python program for the above approach
# Function to find sum of medians
# of all odd-length subarrays
def solve(arr):
ans = 0
n = len(arr)
# Loop to calculate the sum
for i in range(n):
new_arr = []
for j in range(i, n, 1):
new_arr.append(arr[j])
# Odd length subarray
if (len(new_arr)) % 2 == 1:
new_arr.sort()
mid = len(new_arr)//2
ans += new_arr[mid]
return (ans)
# Driver Code
if __name__ == "__main__":
arr = [4, 2, 5, 1]
print(solve(arr))
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to find sum of medians
// of all odd-length subarrays
static int solve(int[] arr) {
int ans = 0;
int n = arr.Length;
// Loop to calculate the sum
for (int i = 0; i < n; i++) {
List<int> new_arr = new List<int>();
for (int j = i; j < n; j++) {
new_arr.Add(arr[j]);
// Odd length subarray
if ((new_arr.Count % 2) == 1) {
new_arr.Sort();
int mid = new_arr.Count / 2;
ans += new_arr[mid];
}
}
}
return ans;
}
// Driver Code
public static void Main() {
int[] arr = { 4, 2, 5, 1 };
Console.Write(solve(arr));
}
}
// This code is contributed by Saurabh Jaiswal
JavaScript
<script>
// javascript program for the above approach
// Function to find sum of medians
// of all odd-length subarrays
function solve(arr) {
var ans = 0;
var n = arr.length;
// Loop to calculate the sum
for (var i = 0; i < n; i++) {
var new_arr= new Array();
for (var j = i; j < n; j++) {
new_arr.push(arr[j]);
// Odd length subarray
if ((new_arr.length % 2) == 1) {
new_arr.sort();
var mid = Math.floor(new_arr.length / 2);
// document.write(mid);
ans += new_arr[mid];
}
}
}
return ans;
}
// Driver Code
var arr = [ 4, 2, 5, 1 ];
document.write(solve(arr));
// This code is contributed by shikhasingrajput
</script>
Time Complexity: O(N3 * Log(N))
Auxiliary Space: O(N)
Note: Instead of sorting array each time, which costs (N*logN), insertion sort can be applied. But still, overall Time Complexity will be O(N3).
Efficient Approach: The median of the sorted array is the value separating the higher half from the lower half in the array. For finding out the median, we only need the middle element, rather than the entire sorted array. The approach of Median of Stream of Running Integers can be applied over here. Follow the steps mentioned below
- Use max and min heaps to calculate the running median.
- Traverse each and every element in the array.
- While creating a new subarray, add an element into the heaps and return median if the size is odd else return 0.
- Max_heap is used to store lower half elements such that the maximum element is at the top and min_heap is used to store higher half elements such that the minimum element is at the top.
- The difference between both the heaps should not be greater than one, and one extra element is always placed in max_heap.
Note: Here max_heap is implemented using min_heap, by just negating the values so that the maximum negative element can be popped.
Below is the implementation of the above approach:
C++
// C++ program for the above approach
#include <bits/stdc++.h>
// Class to find median
class find_median {
public:
// Constructor to declare two heaps
find_median()
{
// Store lower half elements such that
// maximum element is at top
max_heap
= std::priority_queue<int, std::vector<int>,
std::less<int> >();
// Store higher half elements such that
// minimum element is at top
min_heap
= std::priority_queue<int, std::vector<int>,
std::less<int> >();
}
// Function to add element
int add(int val)
{
// If max_heap is empty or current element
// smaller than top of max_heap
if (max_heap.empty() || max_heap.top() > val) {
max_heap.push(-val);
}
else {
min_heap.push(val);
}
// If size of max_heap + 1 less
// than min_heap
if (max_heap.size() + 1 > min_heap.size()) {
val = -max_heap.top();
max_heap.pop();
min_heap.push(val);
}
// If size of min_heap
// less than max_heap
if (min_heap.size() > max_heap.size()) {
val = min_heap.top();
min_heap.pop();
max_heap.push(-val);
}
// Finally if sum of sizes is odd,
// return median
if ((min_heap.size() + max_heap.size()) % 2 == 1) {
return -max_heap.top();
}
// Else return 0
else {
return 0;
}
}
std::priority_queue<int, std::vector<int>,
std::less<int> >
max_heap;
std::priority_queue<int, std::vector<int>,
std::less<int> >
min_heap;
};
// Function to calculate the sum of all odd length subarrays
int solve(std::vector<int> arr)
{
int ans = 0;
// Size of the array
int n = arr.size();
for (int i = 0; i < n; i++) {
// Create an object of class find_median
find_median obj;
for (int j = i; j < n; j++)
{
// Add value to the heaps using object
int val = obj.add(arr[j]);
ans += val;
}
}
return (ans);
}
// Driver Code
int main()
{
std::vector<int> arr = { 4, 2, 5, 1 };
std::cout << solve(arr);
return 0;
}
// This code is contributed by phasing17.
Java
import java.util.*;
// A class to find the median of the array
class FindMedian {
// Declare two heaps
// Store lower half elements such that
// maximum element is at top
private List<Integer> max_heap;
// Store higher half elements such that
// minimum element is at top
private List<Integer> min_heap;
// Constructor to initialize the heaps
public FindMedian() {
max_heap = new ArrayList<>();
min_heap = new ArrayList<>();
}
public int add(int val) {
// len(max_heap) == 0 or curr_element
// smaller than max_heap top
if (max_heap.size() == 0 || max_heap.get(0) > val) {
max_heap.add(-val);
}
else {
min_heap.add(val);
}
// If size of max_heap + 1 greater
// than min_heap
if (max_heap.size() + 1 > min_heap.size()) {
int v = max_heap.get(max_heap.size() - 1);
max_heap.remove(max_heap.size() - 1);
min_heap.add(-v);
}
// If size of min_heap
// greater than max_heap
if (min_heap.size() > max_heap.size()) {
int v = min_heap.get(min_heap.size() - 1);
min_heap.remove(min_heap.size() - 1);
max_heap.add(-v);
}
// Finally if sum of sizes is odd,
// return median
if ((min_heap.size() + max_heap.size()) % 2 == 1) {
return (-max_heap.get(0));
}
// Else return 0
else {
return 0;
}
}
}
class GFG {
// Function to calculate the sum
// of all odd length subarrays
public static int solve(int[] arr) {
int ans = 0;
// Size of the array
int n = arr.length;
for (int i = 0; i < n; i++) {
// Create an object
// of class FindMedian
FindMedian obj = new FindMedian();
for (int j = i; j < n; j++) {
// Add value to the heaps
// using object
int val = obj.add(arr[j]);
ans += val;
}
}
return (ans);
}
// Driver Code
public static void main(String[] args) {
int[] arr = { 4, 2, 5, 1 };
System.out.println(solve(arr));
}
}
Python3
# Python program for the above approach
from heapq import heappush as push, heappop as pop
# Find the sum of medians of odd-length
# subarrays
class find_median():
# Constructor to declare two heaps
def __init__(self):
# Store lower half elements such that
# maximum element is at top
self.max_heap = []
# Store higher half elements such that
# minimum element is at top
self.min_heap = []
def add(self, val):
# len(max_heap) == 0 or curr_element
# smaller than max_heap top
if (len(self.max_heap) == 0 or
self.max_heap[0] > val):
push(self.max_heap, -val)
else:
push(self.min_heap, val)
# If size of max_heap + 1 greater
# than min_heap
if (len(self.max_heap)+1 >
len(self.min_heap)):
val = pop(self.max_heap)
push(self.min_heap, -val)
# If size of min_heap
# greater than max_heap
if (len(self.min_heap) >
len(self.max_heap)):
val = pop(self.min_heap)
push(self.max_heap, -val)
# Finally if sum of sizes is odd,
# return median
if (len(self.min_heap) +
len(self.max_heap)) % 2 == 1:
return (-self.max_heap[0])
# Else return 0
else:
return 0
# Function to calculate the sum
# of all odd length subarrays
def solve(arr):
ans = 0
# Size of the array
n = len(arr)
for i in range(n):
# Create an object
# of class find_median
obj = find_median()
for j in range(i, n, 1):
# Add value to the heaps
# using object
val = obj.add(arr[j])
ans += val
return (ans)
# Driver Code
if __name__ == "__main__":
arr = [4, 2, 5, 1]
print(solve(arr))
C#
// C# Program for the above approach
using System;
using System.Collections.Generic;
// A class to find the median of the array
public class FindMedian
{
// Declare two heaps
// Store lower half elements such that
// maximum element is at top
private List<int> max_heap;
// Store higher half elements such that
// minimum element is at top
private List<int> min_heap;
// Constructor to initialize the heaps
public FindMedian()
{
max_heap = new List<int>();
min_heap = new List<int>();
}
public int Add(int val)
{
// len(max_heap) == 0 or curr_element
// smaller than max_heap top
if (max_heap.Count == 0 || max_heap[0] > val) {
max_heap.Add(-val);
}
else {
min_heap.Add(val);
}
// If size of max_heap + 1 greater
// than min_heap
if (max_heap.Count + 1 > min_heap.Count) {
int v = max_heap[max_heap.Count - 1];
max_heap.RemoveAt(max_heap.Count - 1);
min_heap.Add(-v);
}
// If size of min_heap
// greater than max_heap
if (min_heap.Count > max_heap.Count) {
int v = min_heap[min_heap.Count - 1];
min_heap.RemoveAt(min_heap.Count - 1);
max_heap.Add(-v);
}
// Finally if sum of sizes is odd,
// return median
if ((min_heap.Count + max_heap.Count) % 2 == 1) {
return (-max_heap[0]);
}
// Else return 0
else {
return 0;
}
}
}
public class GFG {
// Function to calculate the sum
// of all odd length subarrays
public static int Solve(int[] arr)
{
int ans = 0;
// Size of the array
int n = arr.Length;
for (int i = 0; i < n; i++) {
// Create an object
// of class find_median
FindMedian obj = new FindMedian();
for (int j = i; j < n; j++) {
// Add value to the heaps
// using object
int val = obj.Add(arr[j]);
ans += val;
}
}
return (ans);
}
// Driver Code
public static void Main()
{
int[] arr = { 4, 2, 5, 1 };
Console.WriteLine(Solve(arr));
}
}
// This code is contributed by vinayetbi1
JavaScript
// JavaScript Program for the above approach
// A class to find the median of the array
class find_median {
// Constructor to declare two heaps
constructor() {
// Store lower half elements such that
// maximum element is at top
this.max_heap = [];
// Store higher half elements such that
// minimum element is at top
this.min_heap = [];
}
add(val) {
// len(max_heap) == 0 or curr_element
// smaller than max_heap top
if (this.max_heap.length == 0 || this.max_heap[0] > val) {
this.max_heap.push(-val);
}
else {
this.min_heap.push(val);
}
// If size of max_heap + 1 greater
// than min_heap
if (this.max_heap.length + 1 > this.min_heap.length) {
let val = this.max_heap.pop();
this.min_heap.push(-val);
}
// If size of min_heap
// greater than max_heap
if (this.min_heap.length > this.max_heap.length) {
let val = this.min_heap.pop();
this.max_heap.push(-val);
}
// Finally if sum of sizes is odd,
// return median
if ((this.min_heap.length + this.max_heap.length) % 2 === 1) {
return (-this.max_heap[0]);
}
// Else return 0
else {
return 0;
}
}
}
// Function to calculate the sum
// of all odd length subarrays
function solve(arr) {
let ans = 0;
// Size of the array
let n = arr.length;
for (let i = 0; i < n; i++) {
// Create an object
// of class find_median
let obj = new find_median();
for (let j = i; j < n; j++) {
// Add value to the heaps
// using object
let val = obj.add(arr[j]);
ans += val;
}
}
return (ans);
}
// Driver Code
let arr = [4, 2, 5, 1];
console.log(solve(arr));
// This code is contributed by vinayetbi1.
Time Complexity: O(N2 * Log(N))
Auxiliary Space: O(N)
Similar Reads
Find number of subarrays with even sum Given an array, find the number of subarrays whose sum is even. Example : Input : arr[] = {1, 2, 2, 3, 4, 1} Output : 9 There are possible subarrays with even sum. The subarrays are 1) {1, 2, 2, 3} Sum = 8 2) {1, 2, 2, 3, 4} Sum = 12 3) {2} Sum = 2 (At index 1) 4) {2, 2} Sum = 4 5) {2, 2, 3, 4, 1} S
15+ min read
Count of Subarrays of given Array with median at least X Given an array arr[]of integers with length N and an integer X, the task is to calculate the number of subarrays with median greater than or equal to the given integer X. Examples: Input: N=4, A = [5, 2, 4, 1], X = 4Output: 7Explanation: For subarray [5], median is 5. (>= 4)For subarray [5, 2], m
9 min read
Median of all non-empty subset sums Given an array, arr[] of size N, the task is to find the median of sums of all possible subsets of the given array. Examples: Input: arr = {2, 3, 3}Output: 5Explanation: Non-Empty Subsets of the given array are: { {2}, {3}, {3}, {2, 3}, {2, 3}, {3, 3}, {2, 3, 3} }. Possible sum of each subset are: {
15+ min read
Length of longest Subarray with equal number of odd and even elements Given an integer array arr[], the task is to find the length of the longest subarray with an equal number of odd and even elements. Examples: Input: arr[] = {1, 2, 1, 2}Output: 4 Explanation: Subarrays in the given array are - {{1}, {1, 2}, {1, 2, 1}, {1, 2, 1, 2}, {2}, {2, 1}, {2, 1, 2}, {1}, {1, 2
12 min read
Balancing Odd-Even Index Sums with Subarray Negation Given an array A[] of size N. The task is to check whether the sum of elements of A on the odd and even indexes is equal or not, where you are allowed to choose a subarray A[i, j] with 1 ⤠i ⤠j ⤠N and multiply â1 by all elements of the subarray. Examples: Input: N = 5, A[] = [1, 5, -2, 3, -1]Outpu
6 min read