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:
- Initialize two pointers, l and r, to mark the left and right boundaries of the current subarray.
- Initialize an unordered_map to store the frequency of elements within the current subarray.
- Iterate through the array from left to right using the right pointer r.
- Increment the frequency of nums[r] in the map.
- If the frequency of nums[r] exceeds k, we need to shrink the window from the left until the frequency new inserted element decrease by one.
- Update the maximum length of the valid subarray if necessary.
- Return the maximum length found.
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)