Smallest subarray having an element with frequency greater than that of other elements
Last Updated :
01 Feb, 2023
Given an array arr of positive integers, the task is to find the smallest length subarray of length more than 1 having an element occurring more times than any other element.
Examples:
Input: arr[] = {2, 3, 2, 4, 5}
Output: 2 3 2
Explanation: The subarray {2, 3, 2} has an element 2 which occurs more number of times any other element in the subarray.
Input: arr[] = {2, 3, 4, 5, 2, 6, 7, 6}
Output: 6 7 6
Explanation: The subarrays {2, 3, 4, 5, 2} and {6, 7, 6} contain an element that occurs more number of times than any other element in them. But the subarray {6, 7, 6} is of minimum length.
Naive Approach: A naive approach to solve the problem can be to find all the subarrays which have an element that meets the given condition and then find the minimum of all those subarrays.
- Initialize a variable result to the maximum possible value of an integer and a hash map unmap to store element frequencies. Initialize two variables maxFreq and secondMaxx to store the maximum and second maximum frequencies seen so far in the current subarray.
- Iterate through the input array arr[] with an outer loop variable i.
- For each value of i, iterate through the array again with an inner loop variable j such that j starts at i and goes up to the end of the array.
- For each value of j, increment the frequency of arr[j] in the hash map unmap.
- If the frequency of arr[j] in unmap is greater than the current value of maxFreq, update secondMaxx with the current value of maxFreq and maxFreq with the frequency of arr[j] in unmap.
- If the current subarray (from i to j) has at least two elements and both maxFreq and secondMaxx are greater than 0, update result with the minimum of its current value and the length of the current subarray.
- After the outer loop finishes, print the final value of result.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void FindSubarray( int arr[], int n)
{
int result = INT_MAX;
for ( int i = 0; i < n; i++) {
unordered_map< int , int > unmap;
int secondMaxx = -1;
int maxFreq = -1;
for ( int j = i; j < n; j++) {
unmap[arr[j]]++;
if (unmap[arr[j]] > maxFreq) {
secondMaxx = maxFreq;
maxFreq = unmap[arr[j]];
}
else if (unmap[arr[j]] > secondMaxx) {
secondMaxx = unmap[arr[j]];
}
if (j - i + 1 > 1 && maxFreq > 0
&& secondMaxx > 0) {
result = min(j - i + 1, result);
}
}
}
cout << result;
}
int main()
{
int arr[] = { 2, 3, 4, 5, 2, 6, 7, 6 };
int n = sizeof (arr) / sizeof (arr[0]);
FindSubarray(arr, n);
return 0;
}
|
Java
import java.util.HashMap;
public class Gfg {
public static void FindSubarray( int [] arr, int n) {
int result = Integer.MAX_VALUE;
for ( int i = 0 ; i < n; i++) {
HashMap<Integer, Integer> hmap = new HashMap<>();
int secondMaxx = - 1 ;
int maxFreq = - 1 ;
for ( int j = i; j < n; j++) {
if (hmap.containsKey(arr[j])) {
hmap.put(arr[j], hmap.get(arr[j]) + 1 );
} else {
hmap.put(arr[j], 1 );
}
if (hmap.get(arr[j]) > maxFreq) {
secondMaxx = maxFreq;
maxFreq = hmap.get(arr[j]);
}
else if (hmap.get(arr[j]) > secondMaxx) {
secondMaxx = hmap.get(arr[j]);
}
if (j - i + 1 > 1 && maxFreq > 0
&& secondMaxx > 0 ) {
result = Math.min(j - i + 1 , result);
}
}
}
System.out.println(result);
}
public static void main(String[] args) {
int [] arr = { 2 , 3 , 4 , 5 , 2 , 6 , 7 , 6 };
int n = arr.length;
FindSubarray(arr, n);
}
}
|
Python3
def FindSubarray(arr, n):
result = float ( 'inf' )
for i in range (n):
unmap = {}
secondMaxx = - 1
maxFreq = - 1
for j in range (i, n):
if arr[j] in unmap:
unmap[arr[j]] + = 1
else :
unmap[arr[j]] = 1
if unmap[arr[j]] > maxFreq:
secondMaxx = maxFreq
maxFreq = unmap[arr[j]]
elif unmap[arr[j]] > secondMaxx:
secondMaxx = unmap[arr[j]]
if j - i + 1 > 1 and maxFreq > 0 and secondMaxx > 0 :
result = min (j - i + 1 , result)
print (result)
arr = [ 2 , 3 , 4 , 5 , 2 , 6 , 7 , 6 ]
n = len (arr)
FindSubarray(arr, n)
|
C#
using System;
using System.Collections.Generic;
class Program {
static void FindSubarray( int [] arr, int n)
{
int result = int .MaxValue;
for ( int i = 0; i < n; i++) {
Dictionary< int , int > unmap
= new Dictionary< int , int >();
int secondMaxx = -1;
int maxFreq = -1;
for ( int j = i; j < n; j++) {
if (!unmap.ContainsKey(arr[j])) {
unmap.Add(arr[j], 1);
}
else {
unmap[arr[j]]++;
}
if (unmap[arr[j]] > maxFreq) {
secondMaxx = maxFreq;
maxFreq = unmap[arr[j]];
}
else if (unmap[arr[j]] > secondMaxx) {
secondMaxx = unmap[arr[j]];
}
if (j - i + 1 > 1 && maxFreq > 0
&& secondMaxx > 0) {
result = Math.Min(j - i + 1, result);
}
}
}
Console.WriteLine(result);
}
static void Main()
{
int [] arr = { 2, 3, 4, 5, 2, 6, 7, 6 };
int n = arr.Length;
FindSubarray(arr, n);
}
}
|
Javascript
const FindSubarray = (arr, n) => {
let result = Number.MAX_SAFE_INTEGER;
for (let i = 0; i < n; i++) {
let unmap = new Map();
let secondMaxx = -1;
let maxFreq = -1;
for (let j = i; j < n; j++) {
unmap.set(arr[j], (unmap.get(arr[j]) || 0) + 1);
if (unmap.get(arr[j]) > maxFreq) {
secondMaxx = maxFreq;
maxFreq = unmap.get(arr[j]);
}
else if (unmap.get(arr[j]) > secondMaxx) {
secondMaxx = unmap.get(arr[j]);
}
if (j - i + 1 > 1 && maxFreq > 0 && secondMaxx > 0) {
result = Math.min(j - i + 1, result);
}
}
}
console.log(result);
};
const arr = [2, 3, 4, 5, 2, 6, 7, 6];
const n = arr.length;
FindSubarray(arr, n);
|
Time Complexity: O(N2)
Auxiliary Space: O(N)
Efficient Approach: The problem can be reduced to find out that if there is any element occurring twice in a subarray, then it can be a potential answer. Because the minimum length of such subarray can be the minimum distance between two same elements
The idea is to use an extra array that maintains the last occurrence of the elements in the given array. Then find the distance between the last occurrence of an element and current position and find the minimum of all such lengths.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
void FindSubarray( int arr[], int n)
{
if (n == 1) {
cout << "No such subarray!"
<< endl;
}
int vis[n + 1];
memset (vis, -1, sizeof (vis));
vis[arr[0]] = 0;
int len = INT_MAX, flag = 0;
int start, end;
for ( int i = 1; i < n; i++) {
int t = arr[i];
if (vis[t] != -1) {
int distance = i - vis[t] + 1;
if (distance < len) {
len = distance;
start = vis[t];
end = i;
}
flag = 1;
}
vis[t] = i;
}
if (flag == 0)
cout << "No such subarray!"
<< endl;
else {
for ( int i = start; i <= end; i++)
cout << arr[i] << " " ;
}
}
int main()
{
int arr[] = { 2, 3, 2, 4, 5 };
int n = sizeof (arr) / sizeof (arr[0]);
FindSubarray(arr, n);
return 0;
}
|
Java
import java.util.*;
class GFG{
public static void FindSubarray( int [] arr,
int n)
{
if (n == 1 )
{
System.out.println( "No such subarray!" );
}
int [] vis = new int [n + 1 ];
Arrays.fill(vis, - 1 );
vis[arr[ 0 ]] = 0 ;
int len = Integer.MAX_VALUE, flag = 0 ;
int start = 0 , end = 0 ;
for ( int i = 1 ; i < n; i++)
{
int t = arr[i];
if (vis[t] != - 1 )
{
int distance = i - vis[t] + 1 ;
if (distance < len)
{
len = distance;
start = vis[t];
end = i;
}
flag = 1 ;
}
vis[t] = i;
}
if (flag == 0 )
System.out.println( "No such subarray!" );
else
{
for ( int i = start; i <= end; i++)
System.out.print(arr[i] + " " );
}
}
public static void main(String[] args)
{
int arr[] = { 2 , 3 , 2 , 4 , 5 };
int n = arr.length;
FindSubarray(arr, n);
}
}
|
Python3
import sys
def FindSubarray(arr, n):
if (n = = 1 ):
print ( "No such subarray!" )
vis = [ - 1 ] * (n + 1 )
vis[arr[ 0 ]] = 0
length = sys.maxsize
flag = 0
for i in range ( 1 , n):
t = arr[i]
if (vis[t] ! = - 1 ):
distance = i - vis[t] + 1
if (distance < length):
length = distance
start = vis[t]
end = i
flag = 1
vis[t] = i
if (flag = = 0 ):
print ( "No such subarray!" )
else :
for i in range (start, end + 1 ):
print (arr[i], end = " " )
if __name__ = = "__main__" :
arr = [ 2 , 3 , 2 , 4 , 5 ]
n = len (arr)
FindSubarray(arr, n)
|
C#
using System;
class GFG{
public static void FindSubarray( int [] arr,
int n)
{
if (n == 1)
{
Console.WriteLine( "No such subarray!" );
}
int [] vis = new int [n + 1];
for ( int i = 0; i < n + 1; i++)
vis[i] = -1;
vis[arr[0]] = 0;
int len = int .MaxValue, flag = 0;
int start = 0, end = 0;
for ( int i = 1; i < n; i++)
{
int t = arr[i];
if (vis[t] != -1)
{
int distance = i - vis[t] + 1;
if (distance < len)
{
len = distance;
start = vis[t];
end = i;
}
flag = 1;
}
vis[t] = i;
}
if (flag == 0)
Console.WriteLine( "No such subarray!" );
else
{
for ( int i = start; i <= end; i++)
Console.Write(arr[i] + " " );
}
}
public static void Main(String[] args)
{
int []arr = { 2, 3, 2, 4, 5 };
int n = arr.Length;
FindSubarray(arr, n);
}
}
|
Javascript
<script>
function FindSubarray(arr, n)
{
if (n == 1)
{
document.write( "No such subarray!" );
}
let vis = new Array(n + 1);
for (let i = 0; i < (n + 1); i++)
vis[i] = -1;
vis[arr[0]] = 0;
let len = Number.MAX_VALUE, flag = 0;
let start = 0, end = 0;
for (let i = 1; i < n; i++)
{
let t = arr[i];
if (vis[t] != -1)
{
let distance = i - vis[t] + 1;
if (distance < len)
{
len = distance;
start = vis[t];
end = i;
}
flag = 1;
}
vis[t] = i;
}
if (flag == 0)
document.write( "No such subarray!" );
else
{
for (let i = start; i <= end; i++)
document.write(arr[i] + " " );
}
}
let arr = [ 2, 3, 2, 4, 5 ];
let n = arr.length;
FindSubarray(arr, n);
</script>
|
Time Complexity: O(N), where n is the length of the array.
Auxiliary Space: O(N).
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...