Open In App

Length of Longest Subarray having at Most K Frequency

Given an integer array arr[]and an integer K, the task is to find the length of the longest subarray such that the frequency of each element is less than or equal to K.

Examples:

Input: arr[] = {10, 20, 30, 10, 20, 30, 10, 20}, K = 2
Output: 6
Explanation: The longest possible subarray is {10, 20, 30, 10, 20, 30} since the values 10, 20 and 30 occur at most twice in this subarray. Note that the subarrays {20, 30, 10, 20, 30, 10} and {30, 10, 20, 30, 10, 20} are also longest possible subarrays.

Input: arr[] = {5, 10, 5, 10, 5, 10}, K = 1
Output: 2
Explanation: The longest possible subarray is {5, 10} since the values 5 and 10 occur at most once in this subarray. Note that the subarray [10, 5] is also longest possible subarray.

Approach: To solve the problem, follow the below idea:

The problem can be solved using Two pointer technique. Start with two pointers l = 0 and r = 0 to mark the starting and ending of valid subarrays. Increment r to increase the length of the subarray and record the frequency of each element. If the frequency of current element becomes greater than K, then move the starting pointer l and decrement the frequency of arr[l] till the frequency of current element becomes <= K. Update the maximum length if the length of current array is greater than the maximum length.

Step-by-step algorithm:

Below is the implementation of the approach:

#include <algorithm>
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;

// Function to find the length of the longest subarray with
// at most K frequency
int maxSubarrayLength(vector<int>& arr, int K)
{
    // Variable to store the maximum length
    int count = 0;
    // Map to store the frequency of each element
    unordered_map<int, int> map;

    int l = 0;
    for (int r = 0; r < arr.size(); r++) {
        // Increment the frequency of the element by 1
        map[arr[r]]++;
        // If the frequency of the element becomes greater
        // than K, then move the left pointer till the
        // frequency becomes less than K
        while (map[arr[r]] > K) {
            map[arr[l]]--;
            l++;
        }
        // Update count if the length of the current
        // subarray is greater than count
        count = max(count, r - l + 1);
    }
    return count;
}

int main()
{
    // Sample Input
    vector<int> arr = { 5, 10, 5, 10, 5, 10 };
    int K = 1;
    cout << maxSubarrayLength(arr, K);
    return 0;
}

// This code is contributed by shivamgupta310570
/*package whatever //do not write package name here */

import java.util.*;

class GFG {
    // Function to find the length of longest subarray with
    // at most K frequency
    public static int maxSubarrayLength(int[] arr, int K)
    {
        // Variable to store the maximum length
        int count = 0;
        // Map to store the frequency of each element
        HashMap<Integer, Integer> map = new HashMap<>();

        int l = 0;
        for (int r = 0; r < arr.length; r++) {
            // Increment the frequency of element by 1
            map.put(arr[r],
                    map.getOrDefault(arr[r], 0) + 1);
            // If frequency of the element becomes greater
            // than K, then move the left pointer till the
            // frequency becomes less than K
            while (map.get(arr[r]) > K) {
                map.put(arr[l],
                        map.getOrDefault(arr[l], 0) - 1);
                l++;
            }
            // Update count if length of the current
            // subarray is greater than count
            count = Math.max(count, r - l + 1);
        }
        return count;
    }
    public static void main(String[] args)
    {
        // Sample Input
        int arr[] = { 5, 10, 5, 10, 5, 10 };
        int K = 1;
        System.out.print(maxSubarrayLength(arr, K));
    }
}
def maxSubarrayLength(arr, K):
    # Variable to store the maximum length
    count = 0
    # Dictionary to store the frequency of each element
    freq_map = {}

    l = 0
    for r in range(len(arr)):
        # Increment the frequency of the element by 1
        freq_map[arr[r]] = freq_map.get(arr[r], 0) + 1
        # If the frequency of the element becomes greater
        # than K, then move the left pointer till the
        # frequency becomes less than K
        while freq_map[arr[r]] > K:
            freq_map[arr[l]] -= 1
            l += 1
        # Update count if the length of the current
        # subarray is greater than count
        count = max(count, r - l + 1)
    return count

if __name__ == "__main__":
    # Sample Input
    arr = [5, 10, 5, 10, 5, 10]
    K = 1
    print(maxSubarrayLength(arr, K))

    # This code is contributed by Ayush Mishra
function maxSubarrayLength(arr, K) {
    // Variable to store the maximum length
    let count = 0;
    // Map to store the frequency of each element
    const map = new Map();

    let l = 0;
    for (let r = 0; r < arr.length; r++) {
        // Increment the frequency of the element by 1
        map.set(arr[r], (map.get(arr[r]) || 0) + 1);
        // If the frequency of the element becomes greater
        // than K, then move the left pointer till the
        // frequency becomes less than K
        while (map.get(arr[r]) > K) {
            map.set(arr[l], map.get(arr[l]) - 1);
            l++;
        }
        // Update count if the length of the current
        // subarray is greater than count
        count = Math.max(count, r - l + 1);
    }
    return count;
}

// Sample Input
const arr = [5, 10, 5, 10, 5, 10];
const K = 1;
console.log(maxSubarrayLength(arr, K));

Output
2

Time Complexity: O(N), where N is the size of input array arr[].
Auxiliary Space: O(N)

Article Tags :