MEX Subarray Count
Last Updated :
08 Dec, 2023
Given an array of size N, each element of the array lies between [0, N-1] i.e., the given array is a permutation. The task is to determine the number of subarrays whose MEX is greater than the Median.
Note: MEX is the smallest whole number that is not present in the array.
Examples:
Input: N=4, arr=[0, 2, 1, 3]
Output: 4
Explanation: The subarrays whose MEX is greater than Median are: [0], [0, 2], [0, 2, 1], and [0, 2, 1, 3].
Input: N=4, arr=[1, 0]
Output: 2
Explanation: The subarrays whose MEX is greater than Median are: [0], [1, 0].
MEX Subarray Count using Two Pointers:
We can firstly observe the MEX of any subarray will be in between 0 to N. So we can calculate the answer for a fixed value of MEX. Now, for a fixed value of MEX , let l be the index of left-most number 0, 1, 2, …. mex-1 and r be the index of right-most number 0, 1, 2, … mex-1. Let curr be the current length of the subarray i.e., curr=(r-l)+1. If curr is less than equal to 2*MEX, then MED of the subarray will arr[l…r] will be in between [0…..MEX-1], so number of subarrays can be calculated with some formulas. If curr greater than 2*MEX then MED of subarray will be greater.
Follow the steps to solve the problem:
- Create the index and frequency array to store index and frequency of elements. Let ans variable store the number of subarrays whose MEX is greater than the Median.
- Maintain two pointer l and r which stores index of left-most number 0, 1, 2, …. mex-1 and r be the index of right-most number 0, 1, 2, … mex-1.
- Run a loop while
mex
is less than or equal to N
:
- Calculate the size of current subarray, curr=(r-l)+1 and let len=2*mex.
- If curr<=len, then Median of subarray is less than mex and we update the answer by some formulas.
- Else, answer won’t be updated.
- Update l, r and mex.
- Return the ans
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int solve(vector< int > a, int N) {
vector< int > idx(N + 2);
vector< int > frq(N + 2, 0);
for ( int i = 0; i < N; i++) {
idx[a[i]] = i;
}
if (N == 1) {
return 1;
}
int ans = 0;
int mex = 1;
int l = idx[0];
int r = idx[0];
frq[0] = 1;
while (mex <= N) {
int num1 = 0, num2 = 0;
int len = mex * 2;
int curr = (r - l + 1);
int op = len - curr;
if (mex == N) {
num1 = l;
num2 = (N - 1) - r;
} else {
if (idx[mex] < l) {
num1 = (l - idx[mex]) - 1;
num2 = (N - 1) - r;
} else {
num1 = l;
num2 = (idx[mex] - r) - 1;
}
}
if (op == 0) {
ans++;
} else if (op > 0) {
num1 = min(op, num1);
num2 = min(op, num2);
if (num1 > num2)
swap(num1, num2);
int ext = (num2 + 1) * (min((op - num2) + 1, num1 + 1));
int rem = max(0, num1 - (op - num2));
int m = num2;
int x = max(0, m - rem);
int ext1 = (m * (m + 1)) / 2;
int ext2 = (x * (x + 1)) / 2;
ans = ans + ext + (ext1 - ext2);
}
if (mex == N)
break ;
if (idx[mex] < l) {
l--;
while (l != idx[mex]) {
frq[a[l]] = 1;
l--;
}
frq[a[l]] = 1;
} else if (idx[mex] > r) {
r++;
while (r != idx[mex]) {
frq[a[r]] = 1;
r++;
}
frq[a[r]] = 1;
}
while (frq[mex] != 0) {
mex++;
}
}
return ans;
}
int main() {
int N = 4;
vector< int > arr = {0, 2, 1, 3};
cout << solve(arr, N);
}
|
Java
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int N = 4 ;
int [] arr = { 0 , 2 , 1 , 3 };
System.out.println(solve(arr, N));
}
public static int solve( int [] a, int N) {
int [] idx = new int [N + 2 ];
int [] frq = new int [N + 2 ];
for ( int i = 0 ; i < N; i++) {
idx[a[i]] = i;
}
if (N == 1 ) {
return 1 ;
}
int ans = 0 ;
int mex = 1 ;
int l = idx[ 0 ];
int r = idx[ 0 ];
frq[ 0 ] = 1 ;
while (mex <= N) {
int num1 = 0 , num2 = 0 ;
int len = mex * 2 ;
int curr = (r - l + 1 );
int op = len - curr;
if (mex == N) {
num1 = l;
num2 = (N - 1 ) - r;
} else {
if (idx[mex] < l) {
num1 = (l - idx[mex]) - 1 ;
num2 = (N - 1 ) - r;
} else {
num1 = l;
num2 = (idx[mex] - r) - 1 ;
}
}
if (op == 0 ) {
ans++;
} else if (op > 0 ) {
num1 = Math.min(op, num1);
num2 = Math.min(op, num2);
if (num1 > num2)
swap(num1, num2);
int ext = (num2 + 1 ) * (Math.min((op - num2) + 1 , num1 + 1 ));
int rem = Math.max( 0 , num1 - (op - num2));
int m = num2;
int x = Math.max( 0 , m - rem);
int ext1 = (m * (m + 1 )) / 2 ;
int ext2 = (x * (x + 1 )) / 2 ;
ans = ans + ext + (ext1 - ext2);
}
if (mex == N)
break ;
if (idx[mex] < l) {
l--;
while (l != idx[mex]) {
frq[a[l]] = 1 ;
l--;
}
frq[a[l]] = 1 ;
} else if (idx[mex] > r) {
r++;
while (r != idx[mex]) {
frq[a[r]] = 1 ;
r++;
}
frq[a[r]] = 1 ;
}
while (frq[mex] != 0 ) {
mex++;
}
}
return ans;
}
public static void swap( int a, int b) {
int temp = a;
a = b;
b = temp;
}
}
|
Python3
def solve(a, N):
idx = [ 0 ] * (N + 2 )
frq = [ 0 ] * (N + 2 )
for i in range (N):
idx[a[i]] = i
if N = = 1 :
return 1
ans = 0
mex = 1
l = idx[ 0 ]
r = idx[ 0 ]
frq[ 0 ] = 1
while mex < = N:
num1 = 0
num2 = 0
len = mex * 2
curr = r - l + 1
op = len - curr
if mex = = N:
num1 = l
num2 = N - 1 - r
else :
if idx[mex] < l:
num1 = l - idx[mex] - 1
num2 = N - 1 - r
else :
num1 = l
num2 = idx[mex] - r - 1
if op = = 0 :
ans + = 1
elif op > 0 :
num1 = min (op, num1)
num2 = min (op, num2)
if num1 > num2:
num1, num2 = num2, num1
ext = (num2 + 1 ) * ( min (op - num2 + 1 , num1 + 1 ))
rem = max ( 0 , num1 - (op - num2))
m = num2
x = max ( 0 , m - rem)
ext1 = (m * (m + 1 )) / / 2
ext2 = (x * (x + 1 )) / / 2
ans = ans + ext + (ext1 - ext2)
if mex = = N:
break
if idx[mex] < l:
l - = 1
while l ! = idx[mex]:
frq[a[l]] = 1
l - = 1
frq[a[l]] = 1
elif idx[mex] > r:
r + = 1
while r ! = idx[mex]:
frq[a[r]] = 1
r + = 1
frq[a[r]] = 1
while frq[mex] ! = 0 :
mex + = 1
return ans
N = 4
arr = [ 0 , 2 , 1 , 3 ]
print (solve(arr, N))
|
C#
using System;
using System.Collections.Generic;
class Program
{
static int Solve(List< int > a, int N)
{
List< int > idx = new List< int >( new int [N + 2]);
List< int > frq = new List< int >( new int [N + 2]);
for ( int i = 0; i < N; i++)
{
idx[a[i]] = i;
}
if (N == 1)
{
return 1;
}
int ans = 0;
int mex = 1;
int l = idx[0];
int r = idx[0];
frq[0] = 1;
while (mex <= N)
{
int num1 = 0, num2 = 0;
int len = mex * 2;
int curr = (r - l + 1);
int op = len - curr;
if (mex == N)
{
num1 = l;
num2 = (N - 1) - r;
}
else
{
if (idx[mex] < l)
{
num1 = (l - idx[mex]) - 1;
num2 = (N - 1) - r;
}
else
{
num1 = l;
num2 = (idx[mex] - r) - 1;
}
}
if (op == 0)
{
ans++;
}
else if (op > 0)
{
num1 = Math.Min(op, num1);
num2 = Math.Min(op, num2);
if (num1 > num2)
Swap( ref num1, ref num2);
int ext = (num2 + 1) * (Math.Min((op - num2) + 1, num1 + 1));
int rem = Math.Max(0, num1 - (op - num2));
int m = num2;
int x = Math.Max(0, m - rem);
int ext1 = (m * (m + 1)) / 2;
int ext2 = (x * (x + 1)) / 2;
ans = ans + ext + (ext1 - ext2);
}
if (mex == N)
break ;
if (idx[mex] < l)
{
l--;
while (l != idx[mex])
{
frq[a[l]] = 1;
l--;
}
frq[a[l]] = 1;
}
else if (idx[mex] > r)
{
r++;
while (r != idx[mex])
{
frq[a[r]] = 1;
r++;
}
frq[a[r]] = 1;
}
while (frq[mex] != 0)
{
mex++;
}
}
return ans;
}
static void Swap( ref int a, ref int b)
{
int temp = a;
a = b;
b = temp;
}
static void Main()
{
int N = 4;
List< int > arr = new List< int > { 0, 2, 1, 3 };
Console.WriteLine(Solve(arr, N));
}
}
|
Javascript
function solve(a, N) {
let idx = new Array(N + 2).fill(0);
let frq = new Array(N + 2).fill(0);
for (let i = 0; i < N; i++) {
idx[a[i]] = i;
}
if (N === 1) {
return 1;
}
let ans = 0;
let mex = 1;
let l = idx[0];
let r = idx[0];
frq[0] = 1;
while (mex <= N) {
let num1 = 0, num2 = 0;
let len = mex * 2;
let curr = r - l + 1;
let op = len - curr;
if (mex === N) {
num1 = l;
num2 = (N - 1) - r;
}
else {
if (idx[mex] < l) {
num1 = (l - idx[mex]) - 1;
num2 = (N - 1) - r;
}
else {
num1 = l;
num2 = (idx[mex] - r) - 1;
}
}
if (op === 0) {
ans++;
}
else if (op > 0) {
num1 = Math.min(op, num1);
num2 = Math.min(op, num2);
if (num1 > num2) {
[num1, num2] = [num2, num1];
}
let ext = (num2 + 1) * Math.min((op - num2) + 1, num1 + 1);
let rem = Math.max(0, num1 - (op - num2));
let m = num2;
let x = Math.max(0, m - rem);
let ext1 = (m * (m + 1)) / 2;
let ext2 = (x * (x + 1)) / 2;
ans = ans + ext + (ext1 - ext2);
}
if (mex === N) {
break ;
}
if (idx[mex] < l) {
l--;
while (l !== idx[mex]) {
frq[a[l]] = 1;
l--;
}
frq[a[l]] = 1;
}
else if (idx[mex] > r) {
r++;
while (r !== idx[mex]) {
frq[a[r]] = 1;
r++;
}
frq[a[r]] = 1;
}
while (frq[mex] !== 0) {
mex++;
}
}
return ans;
}
let N = 4;
let arr = [0, 2, 1, 3];
console.log(solve(arr, N));
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...