Count of Subarrays of given Array with median at least X
Last Updated :
09 Mar, 2023
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 = 4
Output: 7
Explanation: For subarray [5], median is 5. (>= 4)
For subarray [5, 2], median is 5. (>= 4)
For subarray [5, 2, 4], median is 4. (>= 4)
For subarray [5, 2, 4, 1], median is 4. (>= 4)
For subarray [2, 4], median is 4. (>= 4)
For subarray [4], median is 4. (>= 4)
For subarray [4, 1], median is 4. (>= 4)
Input: N = [3, 7, 2, 0, 1, 5], X = 10
Output: 0
Explanation: There are no subarrays with median greater than or equal to X.
Approach: The problem can be solved based on the following idea.
To find a subarray with median greater or equal to X at least half of the elements should be greater than or equal to X.
Follow the below steps to implement the above idea:
- Replace each element of an array with 1 if it is greater than or equal to X, else replace it with -1.
- Based on the above idea, for the new array, median of any subarray to be greater than or equal to X, its sum of elements should be greater than or equal to 0.
- For calculating the number of subarray with a sum greater than or equal to 0:
- Find prefix sum up to each index of the new array.
- Traverse the newly created prefix array starting from index 1 and calculate the number of elements before it with a value less than or equal to the current value.
- Add all those in the final answer as they will also form a subarray with the current one satisfying all conditions.
- After finding it for an index, add the current value to a multiset.
- Return the final answer.
Note: For efficiently calculating the number of elements with a value less than or equal to Y, use policy-based data structures.
Below is the implementation of the above approach:
C++
// C++ code to implement the above approach
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <functional>
#include <iostream>
using namespace __gnu_pbds;
using namespace std;
// A new data structure defined.
typedef tree<int, null_type, less_equal<int>, rb_tree_tag,
tree_order_statistics_node_update>
ordered_set;
// Function to find the Number of
// subarrays with median greater than
// or equal to X.
long long findNumberOfSubarray(int arr[],
int n, int X)
{
// Build new array by comparing it with X
int new_array[n];
for (int i = 0; i < n; i++) {
if (arr[i] >= X) {
new_array[i] = 1;
}
else {
new_array[i] = -1;
}
}
// Build new array in which
// at i-th index, Sum of first i elements
// are stored
int pref_sum[n];
pref_sum[0] = new_array[0];
for (int i = 1; i < n; i++) {
pref_sum[i] = pref_sum[i - 1]
+ new_array[i];
}
// Store the answer
// Using long long because
// it can exceed the storage limit of int
long long ans = 0;
// For storing already traversed values
ordered_set s;
s.insert(0);
// Iterating forwards from 0 to n-1.
for (int i = 0; i < n; i++) {
int less_than
= s.order_of_key(pref_sum[i] + 1);
ans += less_than;
s.insert(pref_sum[i]);
}
return ans;
}
// Driver Code
int main()
{
int N = 4, X = 4;
int arr[] = { 5, 2, 4, 1 };
// Function call
long long ans
= findNumberOfSubarray(arr, N, X);
cout << ans;
return 0;
}
Java
// Java code to implement the above approach
import java.util.*;
class GFG {
// Function to find the Number of
// subarrays with median greater than
// or equal to X.
public static int findNumberOfSubarray(int[] arr, int n, int X) {
int[] newArray = new int[n];
for (int i = 0; i < n; i++) {
if (arr[i] >= X) {
newArray[i] = 1;
} else {
newArray[i] = -1;
}
}
// Build new array in which
// at i-th index, Sum of first i elements
// are stored
int[] prefSum = new int[n];
prefSum[0] = newArray[0];
for (int i = 1; i < n; i++) {
prefSum[i] = prefSum[i - 1] + newArray[i];
}
int ans = 0;
HashSet<Integer> set = new HashSet<>();
set.add(0);
// Iterating forwards from 0 to n-1.
for (int i = 0; i < n; i++) {
int lessThan = Collections.binarySearch(new ArrayList<>(set), prefSum[i] + 1);
if (lessThan < 0) {
lessThan = -(lessThan + 1);
}
if (set.contains(prefSum[i] + 1)) {
lessThan++;
}
ans += lessThan;
set.add(prefSum[i]);
}
return ans;
}
// Driver Code
public static void main(String[] args) {
int N = 4, X = 4;
int[] arr = {5, 2, 4, 1};
int ans = findNumberOfSubarray(arr, N, X);
System.out.println(ans);
}
}
Python3
# python3 code to implement the above approach
import bisect
# Function to find the Number of
# subarrays with median greater than
# or equal to X.
def findNumberOfSubarray(arr, n, X):
# Build new array by comparing it with X
new_array = [0 for _ in range(n)]
for i in range(0, n):
if (arr[i] >= X):
new_array[i] = 1
else:
new_array[i] = -1
# Build new array in which
# at i-th index, Sum of first i elements
# are stored
pref_sum = [0 for _ in range(n)]
pref_sum[0] = new_array[0]
for i in range(1, n):
pref_sum[i] = pref_sum[i - 1] + new_array[i]
# Store the answer
# Using long long because
# it can exceed the storage limit of int
ans = 0
# For storing already traversed values
s = set()
s.add(0)
# Iterating forwards from 0 to n-1.
for i in range(0, n):
less_than = bisect.bisect_left(
sorted(s), pref_sum[i]+1, lo=0, hi=len(s))
if pref_sum[i] + 1 in s:
less_than += 1
ans += less_than
s.add(pref_sum[i])
return ans
# Driver Code
if __name__ == "__main__":
N, X = 4, 4
arr = [5, 2, 4, 1]
# Function call
ans = findNumberOfSubarray(arr, N, X)
print(ans)
# This code is contributed by rakeshsahni
C#
// C# code to implement the equivalent of the above Java code
using System;
using System.Collections.Generic;
class GFG
{
// Function to find the number of subarrays with
// median greater than or equal to X
public static int findNumberOfSubarray(int[] arr, int n, int X)
{
// Create a new array where elements >= X are marked
// as 1 and elements < X are marked as -1
int[] newArray = new int[n];
for (int i = 0; i < n; i++)
{
if (arr[i] >= X)
{
newArray[i] = 1;
}
else
{
newArray[i] = -1;
}
}
// Build a new array where the sum of the first
// i elements is stored at the i-th index
int[] prefSum = new int[n];
prefSum[0] = newArray[0];
for (int i = 1; i < n; i++)
{
prefSum[i] = prefSum[i - 1] + newArray[i];
}
int ans = 0;
// Store the prefix sum values in a HashSet
HashSet<int> set = new HashSet<int>();
set.Add(0);
// Iterate forwards from 0 to n-1
for (int i = 0; i < n; i++)
{
// Find the number of elements less than (prefSum[i] + 1) using binary search
int lessThan = Array.BinarySearch(new List<int>(set).ToArray(), prefSum[i] + 1);
if (lessThan < 0)
{
lessThan = -(lessThan + 1);
}
// If (prefSum[i] + 1) is in the set, increment lessThan
if (set.Contains(prefSum[i] + 1))
{
lessThan++;
}
// Add the number of subarrays ending at i with median >= X
ans += lessThan;
// Add the current prefix sum value to the set
set.Add(prefSum[i]);
}
return ans;
}
// Driver Code
static void Main(string[] args)
{
int N = 4, X = 4;
int[] arr = { 5, 2, 4, 1 };
int ans = findNumberOfSubarray(arr, N, X);
Console.WriteLine(ans);
}
}
JavaScript
// javascript code to implement the above approach
// Function to find the Number of
// subarrays with median greater than
// or equal to X.
function findNumberOfSubarray(arr, n, X) {
// Build new array by comparing it with X
let new_array = Array(n).fill(0);
for (let i = 0; i < n; i++) {
if (arr[i] >= X) {
new_array[i] = 1;
} else {
new_array[i] = -1;
}
}
// Build new array in which
// at i-th index, Sum of first i elements
// are stored
let pref_sum = Array(n).fill(0);
pref_sum[0] = new_array[0];
for (let i = 1; i < n; i++) {
pref_sum[i] = pref_sum[i - 1] + new_array[i];
}
// Store the answer
// Using BigInt because it can exceed the storage limit of int
let ans = BigInt(0);
// For storing already traversed values
let s = new Set();
s.add(0);
// Iterating forwards from 0 to n-1.
for (let i = 0; i < n; i++) {
// less_than = bisect.bisect_left(sorted(s), pref_sum[i]+1, lo=0, hi=len(s))
let sortedS = Array.from(s).sort(function(a, b) {
return a - b
});
let less_than = bisect_left(sortedS, pref_sum[i] + 1, 0, sortedS.length);
if (s.has(pref_sum[i] + 1)) {
less_than += 1;
}
ans += BigInt(less_than);
s.add(pref_sum[i]);
}
return ans;
}
// binary search equivalent to Python's bisect.bisect_left
function bisect_left(sortedArr, x, lo, hi) {
lo = lo || 0;
hi = hi || sortedArr.length;
while (lo < hi) {
let mid = (lo + hi) >>> 1;
if (sortedArr[mid] < x) {
lo = mid + 1;
} else {
hi = mid;
}
}
return lo;
}
// Driver Code
let N = 4,
X = 4;
let arr = [5, 2, 4, 1];
// Function call
let ans = findNumberOfSubarray(arr, N, X);
console.log(ans);
// This code is contributed by phasing17
Time Complexity: O(N * logN)
Auxiliary Space: O(N)
Similar Reads
Count of subarrays of size K with average at least M Given an array arr[] consisting of N integers and two positive integers K and M, the task is to find the number of subarrays of size K whose average is at least M. Examples: Input: arr[] = {2, 3, 3, 4, 4, 4, 5, 6, 6}, K = 3, M = 4Output: 4Explanation:Below are the subarrays of size K(= 3) whose aver
7 min read
Count of pairs of Array elements with average at least K Given an array A[] of size N consisting of N integers, the task is to count the number of pairs such that their average is greater or equal to K. Example: Input: N = 4, K = 3, A = {5, 1, 3, 4}Output: 4Explanation: (5, 1), (5, 3), (5, 4) and (3, 4) are the required pairs with average greater or equal
11 min read
Find largest median of a sub array with length at least K Given an array arr[] of length N (1<= arr[i] <= N) and an integer K. The task is to find the largest median of any subarray in arr[] of at least K size. Examples: Input: arr[] = {1, 2, 3, 2, 1}, K = 3 Output: 2Explanation: Here the median of all possible sub arrays with length >= K is 2, so
14 min read
Count Subarrays With At Most K Distinct Elements Given an array arr[] and an integer k, the task is to find the count of subarrays such that each subarray has at most k distinct elements.Examples:Input: arr[] = [1, 2, 2, 3], k = 2 Output: 9Explanation: Subarrays with at most 2 distinct elements are: [1], [2], [2], [3], [1, 2], [2, 2], [2, 3], [1,
9 min read
Find the sum of medians of all odd length subarrays 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: 18Explanation : 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] -> Me
12 min read
Count subarrays with equal number of 1's and 0's Given an array arr[] of size n containing 0 and 1 only. The problem is to count the subarrays having an equal number of 0's and 1's. Examples: Input: arr[] = {1, 0, 0, 1, 0, 1, 1}Output: 8Explanation: The index range for the 8 sub-arrays are: (0, 1), (2, 3), (0, 3), (3, 4), (4, 5)(2, 5), (0, 5), (1,
14 min read
Count of subarrays with average K Given an array arr[] of size N, the task is to count the number of subarrays having an average exactly equal to k.Examples:Input: arr[ ] = {1, 4, 2, 6, 10}, N = 5, K = 4Output: 3Explanation: The subarrays with an average equal to 4 are {4}, {2, 6}, {4, 2, 6}.Input: arr[ ] = {12, 5, 3, 10, 4, 8, 10,
11 min read
Count of subarrays with digit sum equals to X Given an array arr[] of length N and integer X, the task is to count no of subarrays having digit sum equal to X. Examples: Input: arr[] = {10, 5, 13, 20, 9}, X = 6Output: 2Explanation: There are two subarrays which is having digit sum equal to 6. {10, 5} => (1 + 0) + 5 = 6 and {13 , 20} => (1
9 min read
Count of Subarrays in an array containing numbers from 1 to the length of subarray Given an array arr[] of length N containing all elements from 1 to N, the task is to find the number of sub-arrays that contain numbers from 1 to M, where M is the length of the sub-array. Examples: Input: arr[] = {4, 1, 3, 2, 5, 6} Output: 5 Explanation: Desired Sub-arrays = { {4, 1, 3, 2}, {1}, {1
7 min read
Generate a Matrix with mean of each subarray of each row as an integer Given two integers M and N, the task is to generate an MxN matrix having elements in range [1, MxN] such that the average of any subarray of any row is an integer. If it is not possible to do so, return -1. Examples: Input: M = 2, N = 3Output: 1 3 5 2 4 6 Explanation: Subarrays of first row with siz
8 min read