Find minimum subarray length to reduce frequency (original) (raw)

Last Updated : 23 Jul, 2025

Given an array **arr[] of length **N and a positive integer **k, the task is to find the **minimum length of the subarray that needs to be removed from the given array such that the frequency of the remaining elements in the array is less than or equal to **k.

**Examples:

**Input: n = 4, arr[] = {3, 1, 3, 6}, k = 1
**Output: 1
**Explanation: We can see that only 3 is having frequency 2 that is greater than k. So we can remove the 3 at the start of the array to that frequency of all elements become less than or equal to k. Thus the minimum length of the subarray to be removed is 1.

**Input: n = 6, arr[] = {1, 2, 3, 3, 2, 1}, k = 1
**Output: 3
**Explanation: We Can remove the subarray {1, 2, 3} which is the minimum possible length subarray after being removed making the frequency of remaining elements less than or equal to k.

**Approach: This can be solved with the following idea:

This problem can be solved using **Binary Search and **Sliding Window Technique****.**

Below are the steps involved in the implementation of the code:

Below is the implementation of the above approach:

C++ `

#include <bits/stdc++.h> using namespace std;

// Function to find minimum length // needed to be removed int minLength(int n, int k, vector& arr) {

// Map to keep the count of
// Frequency
unordered_map<int, int> f;

int cnt = 0;
for (int i = 0; i < n; i++) {
    f[arr[i]]++;
    if (f[arr[i]] > k)
        cnt++;
}

int l = 0, r = n;
int ans = n;

// Binary search
while (l <= r) {
    int mid = l + (r - l) / 2;
    for (int i = 0; i < mid; i++) {
        if (f[arr[i]] > k)
            cnt--;
        f[arr[i]]--;
    }
    if (cnt == 0) {
        ans = min(ans, mid);
        r = mid - 1;
        for (int i = 0; i < mid; i++) {
            f[arr[i]]++;
            if (f[arr[i]] > k)
                cnt++;
        }
        continue;
    }
    bool flag = false;

    // If particular length is possible
    for (int i = mid; i < n; i++) {
        if (f[arr[i - mid]] >= k)
            cnt++;
        f[arr[i - mid]]++;

        if (f[arr[i]] > k)
            cnt--;
        f[arr[i]]--;

        if (cnt == 0) {
            for (int j = i - mid + 1; j <= i; j++) {
                f[arr[j]]++;
                if (f[arr[j]] > k)
                    cnt++;
            }
            flag = true;
            break;
        }
    }
    if (flag) {
        ans = min(ans, mid);
        r = mid - 1;
    }
    else {
        l = mid + 1;
        for (int i = n - mid; i < n; i++) {
            f[arr[i]]++;
            if (f[arr[i]] > k)
                cnt++;
        }
    }
}

// Return the ans
return ans;

}

// Driver code int main() { int n = 4; int k = 1; vector arr = { 3, 1, 2, 3 };

// Function call
cout << minLength(n, k, arr);
return 0;

}

Java

import java.util.HashMap; import java.util.Map; import java.util.Vector;

class GFG { // Function to find minimum length // needed to be removed static int minLength(int n, int k, Vector arr) {

    // Map to keep the count of Frequency
    Map<Integer, Integer> f = new HashMap<>();

    int cnt = 0;
    for (int i = 0; i < n; i++) {
        f.put(arr.get(i), f.getOrDefault(arr.get(i), 0) + 1);
        if (f.get(arr.get(i)) > k)
            cnt++;
    }

    int l = 0, r = n;
    int ans = n;

    // Binary search
    while (l <= r) {
        int mid = l + (r - l) / 2;
        for (int i = 0; i < mid; i++) {
            if (f.get(arr.get(i)) > k)
                cnt--;
            f.put(arr.get(i), f.get(arr.get(i)) - 1);
        }
        if (cnt == 0) {
            ans = Math.min(ans, mid);
            r = mid - 1;
            for (int i = 0; i < mid; i++) {
                f.put(arr.get(i), f.get(arr.get(i)) + 1);
                if (f.get(arr.get(i)) > k)
                    cnt++;
            }
            continue;
        }
        boolean flag = false;

        // If particular length is possible
        for (int i = mid; i < n; i++) {
            if (f.get(arr.get(i - mid)) >= k)
                cnt++;
            f.put(arr.get(i - mid), f.get(arr.get(i - mid)) + 1);

            if (f.get(arr.get(i)) > k)
                cnt--;
            f.put(arr.get(i), f.get(arr.get(i)) - 1);

            if (cnt == 0) {
                for (int j = i - mid + 1; j <= i; j++) {
                    f.put(arr.get(j), f.get(arr.get(j)) + 1);
                    if (f.get(arr.get(j)) > k)
                        cnt++;
                }
                flag = true;
                break;
            }
        }
        if (flag) {
            ans = Math.min(ans, mid);
            r = mid - 1;
        } else {
            l = mid + 1;
            for (int i = n - mid; i < n; i++) {
                f.put(arr.get(i), f.get(arr.get(i)) + 1);
                if (f.get(arr.get(i)) > k)
                    cnt++;
            }
        }
    }

    // Return the ans
    return ans;
}
// Nikunj Sonigara
public static void main(String[] args) {
    int n = 4;
    int k = 1;
    Vector<Integer> arr = new Vector<>(4);
    arr.add(3);
    arr.add(1);
    arr.add(2);
    arr.add(3);

    // Function call
    System.out.println(minLength(n, k, arr));
}

}

Python3

Python code for the above approach

from typing import List from collections import defaultdict

Function to find minimum length needed to be removed

def min_length(n: int, k: int, arr: List[int]) -> int:

# Dictionary to keep the count of frequency
f = defaultdict(int)

cnt = 0
for i in range(n):
    f[arr[i]] += 1
    if f[arr[i]] > k:
        cnt += 1

l = 0
r = n
ans = n

# Binary search
while l <= r:
    mid = l + (r - l) // 2
    for i in range(mid):
        if f[arr[i]] > k:
            cnt -= 1
        f[arr[i]] -= 1
    if cnt == 0:
        ans = min(ans, mid)
        r = mid - 1
        for i in range(mid):
            f[arr[i]] += 1
            if f[arr[i]] > k:
                cnt += 1
        continue
    flag = False

    # If a particular length is possible
    for i in range(mid, n):
        if f[arr[i - mid]] >= k:
            cnt += 1
        f[arr[i - mid]] += 1

        if f[arr[i]] > k:
            cnt -= 1
        f[arr[i]] -= 1

        if cnt == 0:
            for j in range(i - mid + 1, i + 1):
                f[arr[j]] += 1
                if f[arr[j]] > k:
                    cnt += 1
            flag = True
            break
    if flag:
        ans = min(ans, mid)
        r = mid - 1
    else:
        l = mid + 1
        for i in range(n - mid, n):
            f[arr[i]] += 1
            if f[arr[i]] > k:
                cnt += 1

# Return the answer
return ans

Driver code

if name == "main": n = 4 k = 1 arr = [3, 1, 2, 3]

# Function call
print(min_length(n, k, arr))

C#

// c# code for the above approach

using System; using System.Collections.Generic;

class GFG { // Function to find minimum length // needed to be removed static int MinLength(int n, int k, List arr) { // Dictionary to keep the count of Frequency Dictionary<int, int> f = new Dictionary<int, int>();

    int cnt = 0;
    for (int i = 0; i < n; i++)
    {
        if (f.ContainsKey(arr[i]))
            f[arr[i]]++;
        else
            f[arr[i]] = 1;

        if (f[arr[i]] > k)
            cnt++;
    }

    int l = 0, r = n;
    int ans = n;

    // Binary search
    while (l <= r)
    {
        int mid = l + (r - l) / 2;
        for (int i = 0; i < mid; i++)
        {
            if (f[arr[i]] > k)
                cnt--;

            f[arr[i]]--;
        }

        if (cnt == 0)
        {
            ans = Math.Min(ans, mid);
            r = mid - 1;

            for (int i = 0; i < mid; i++)
            {
                f[arr[i]]++;
                if (f[arr[i]] > k)
                    cnt++;
            }

            continue;
        }

        bool flag = false;

        // If a particular length is possible
        for (int i = mid; i < n; i++)
        {
            if (f[arr[i - mid]] >= k)
                cnt++;

            f[arr[i - mid]]++;

            if (f[arr[i]] > k)
                cnt--;

            f[arr[i]]--;

            if (cnt == 0)
            {
                for (int j = i - mid + 1; j <= i; j++)
                {
                    f[arr[j]]++;
                    if (f[arr[j]] > k)
                        cnt++;
                }

                flag = true;
                break;
            }
        }

        if (flag)
        {
            ans = Math.Min(ans, mid);
            r = mid - 1;
        }
        else
        {
            l = mid + 1;

            for (int i = n - mid; i < n; i++)
            {
                f[arr[i]]++;
                if (f[arr[i]] > k)
                    cnt++;
            }
        }
    }

    // Return the ans
    return ans;
}

// Nikunj Sonigara
public static void Main(string[] args)
{
    int n = 4;
    int k = 1;
    List<int> arr = new List<int> { 3, 1, 2, 3 };

    // Function call
    Console.WriteLine(MinLength(n, k, arr));
}

}

JavaScript

//JavaScript code function minLength(n, k, arr) { const f = new Map();

let cnt = 0;
for (let i = 0; i < n; i++) {
    if (!f.has(arr[i])) {
        f.set(arr[i], 1);
    } else {
        f.set(arr[i], f.get(arr[i]) + 1);
        if (f.get(arr[i]) > k) {
            cnt++;
        }
    }
}

let l = 0, r = n;
let ans = n;

while (l <= r) {
    const mid = l + Math.floor((r - l) / 2);
    for (let i = 0; i < mid; i++) {
        if (f.get(arr[i]) > k) {
            cnt--;
        }
        f.set(arr[i], f.get(arr[i]) - 1);
    }
    if (cnt === 0) {
        ans = Math.min(ans, mid);
        r = mid - 1;
        for (let i = 0; i < mid; i++) {
            f.set(arr[i], f.get(arr[i]) + 1);
            if (f.get(arr[i]) > k) {
                cnt++;
            }
        }
        continue;
    }
    let flag = false;
    for (let i = mid; i < n; i++) {
        if (f.get(arr[i - mid]) >= k) {
            cnt++;
        }
        f.set(arr[i - mid], f.get(arr[i - mid]) + 1);
        
        if (f.get(arr[i]) > k) {
            cnt--;
        }
        f.set(arr[i], f.get(arr[i]) - 1);

        if (cnt === 0) {
            for (let j = i - mid + 1; j <= i; j++) {
                f.set(arr[j], f.get(arr[j]) + 1);
                if (f.get(arr[j]) > k) {
                    cnt++;
                }
            }
            flag = true;
            break;
        }
    }
    if (flag) {
        ans = Math.min(ans, mid);
        r = mid - 1;
    } else {
        l = mid + 1;
        for (let i = n - mid; i < n; i++) {
            f.set(arr[i], f.get(arr[i]) + 1);
            if (f.get(arr[i]) > k) {
                cnt++;
            }
        }
    }
}
return ans;

}

// Driver code const n = 4; const k = 1; const arr = [3, 1, 2, 3];

// Function call console.log(minLength(n, k, arr)); //Contributed by Aditi Tyagi

`

**Time Complexity: O(N*logN)
**Auxiliary Space: O(N)