Given N elements and a number K, find the longest subarray which has not more than K distinct elements.(It can have less than K)

**Examples:**

Input : arr[] = {1, 2, 3, 4, 5} k = 6 Output : 1 2 3 4 5 Explanation: The whole array has only 5 distinct elements which is less than k, so we print the array itself. Input: arr[] = {6, 5, 1, 2, 3, 2, 1, 4, 5} k = 3 Output: 1 2 3 2 1, The output is the longest subarray with 3 distinct elements.

A **naive approach** will be to be traverse in the array and use hashing for every sub-arrays, and check for the longest sub-array possible with no more than K distinct elements.

An **efficient approach** is to use the concept of *two pointers* where we maintain a hash to count for occurrences of elements. We start from the beginning and keep a count of distinct elements till the number exceeds k. Once it exceeds K, we start decreasing the count of the elements in the hash from where the sub-array started and reduce our length as the sub-arrays gets decreased so the pointer moves to the right. We keep removing elements till we again get k distinct elements. We continue this process till we again have more than k distinct elements and keep the left pointer constant till then. We update our start and end according to that if the new sub-array length is more than the previous one.

## C++

`// CPP program to find longest subarray with ` `// k or less distinct elements. ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `// function to print the longest sub-array ` `void` `longest(` `int` `a[], ` `int` `n, ` `int` `k) ` `{ ` ` ` `unordered_map<` `int` `, ` `int` `> freq; ` ` ` ` ` `int` `start = 0, end = 0, now = 0, l = 0; ` ` ` `for` `(` `int` `i = 0; i < n; i++) { ` ` ` ` ` `// mark the element visited ` ` ` `freq[a[i]]++; ` ` ` ` ` `// if its visited first time, then increase ` ` ` `// the counter of distinct elements by 1 ` ` ` `if` `(freq[a[i]] == 1) ` ` ` `now++; ` ` ` ` ` `// When the counter of distinct elements ` ` ` `// increases from k, then reduce it to k ` ` ` `while` `(now > k) { ` ` ` ` ` `// from the left, reduce the number of ` ` ` `// time of visit ` ` ` `freq[a[l]]--; ` ` ` ` ` `// if the reduced visited time element ` ` ` `// is not present in further segment ` ` ` `// then decrease the count of distinct ` ` ` `// elements ` ` ` `if` `(freq[a[l]] == 0) ` ` ` `now--; ` ` ` ` ` `// increase the subsegment mark ` ` ` `l++; ` ` ` `} ` ` ` ` ` `// check length of longest sub-segment ` ` ` `// when greater then previous best ` ` ` `// then change it ` ` ` `if` `(i - l + 1 >= end - start + 1) ` ` ` `end = i, start = l; ` ` ` `} ` ` ` ` ` `// print the longest sub-segment ` ` ` `for` `(` `int` `i = start; i <= end; i++) ` ` ` `cout << a[i] << ` `" "` `; ` `} ` ` ` `// driver program to test the above function ` `int` `main() ` `{ ` ` ` `int` `a[] = { 6, 5, 1, 2, 3, 2, 1, 4, 5 }; ` ` ` `int` `n = ` `sizeof` `(a) / ` `sizeof` `(a[0]); ` ` ` `int` `k = 3; ` ` ` `longest(a, n, k); ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

## Java

`// Java program to find longest subarray with ` `// k or less distinct elements. ` `import` `java.util.*; ` ` ` `class` `GFG ` `{ ` ` ` `// function to print the longest sub-array ` `static` `void` `longest(` `int` `a[], ` `int` `n, ` `int` `k) ` `{ ` ` ` `int` `[] freq = ` `new` `int` `[` `7` `]; ` ` ` ` ` `int` `start = ` `0` `, end = ` `0` `, now = ` `0` `, l = ` `0` `; ` ` ` `for` `(` `int` `i = ` `0` `; i < n; i++) ` ` ` `{ ` ` ` ` ` `// mark the element visited ` ` ` `freq[a[i]]++; ` ` ` ` ` `// if its visited first time, then increase ` ` ` `// the counter of distinct elements by 1 ` ` ` `if` `(freq[a[i]] == ` `1` `) ` ` ` `now++; ` ` ` ` ` `// When the counter of distinct elements ` ` ` `// increases from k, then reduce it to k ` ` ` `while` `(now > k) ` ` ` `{ ` ` ` ` ` `// from the left, reduce the number of ` ` ` `// time of visit ` ` ` `freq[a[l]]--; ` ` ` ` ` `// if the reduced visited time element ` ` ` `// is not present in further segment ` ` ` `// then decrease the count of distinct ` ` ` `// elements ` ` ` `if` `(freq[a[l]] == ` `0` `) ` ` ` `now--; ` ` ` ` ` `// increase the subsegment mark ` ` ` `l++; ` ` ` `} ` ` ` ` ` `// check length of longest sub-segment ` ` ` `// when greater then previous best ` ` ` `// then change it ` ` ` `if` `(i - l + ` `1` `>= end - start + ` `1` `) ` ` ` `{ ` ` ` `end = i; ` ` ` `start = l; ` ` ` `} ` ` ` `} ` ` ` ` ` `// print the longest sub-segment ` ` ` `for` `(` `int` `i = start; i <= end; i++) ` ` ` `System.out.print(a[i]+` `" "` `); ` `} ` ` ` `// Driver code ` `public` `static` `void` `main(String args[]) ` `{ ` ` ` `int` `a[] = { ` `6` `, ` `5` `, ` `1` `, ` `2` `, ` `3` `, ` `2` `, ` `1` `, ` `4` `, ` `5` `}; ` ` ` `int` `n = a.length; ` ` ` `int` `k = ` `3` `; ` ` ` `longest(a, n, k); ` `} ` `} ` ` ` `// This code is contributed by ` `// Surendra_Gangwar ` |

*chevron_right*

*filter_none*

## Python 3

`# Python 3 program to find longest ` `# subarray with k or less distinct elements. ` ` ` `# function to print the longest sub-array ` `def` `longest(a, n, k): ` ` ` ` ` `freq ` `=` `[` `0` `] ` `*` `n ` ` ` ` ` `start ` `=` `0` ` ` `end ` `=` `0` ` ` `now ` `=` `0` ` ` `l ` `=` `0` ` ` `for` `i ` `in` `range` `(n): ` ` ` ` ` `# mark the element visited ` ` ` `freq[a[i]] ` `+` `=` `1` ` ` ` ` `# if its visited first time, then increase ` ` ` `# the counter of distinct elements by 1 ` ` ` `if` `(freq[a[i]] ` `=` `=` `1` `): ` ` ` `now ` `+` `=` `1` ` ` ` ` `# When the counter of distinct elements ` ` ` `# increases from k, then reduce it to k ` ` ` `while` `(now > k) : ` ` ` ` ` `# from the left, reduce the number ` ` ` `# of time of visit ` ` ` `freq[a[l]] ` `-` `=` `1` ` ` ` ` `# if the reduced visited time element ` ` ` `# is not present in further segment ` ` ` `# then decrease the count of distinct ` ` ` `# elements ` ` ` `if` `(freq[a[l]] ` `=` `=` `0` `): ` ` ` `now ` `-` `=` `1` ` ` ` ` `# increase the subsegment mark ` ` ` `l ` `+` `=` `1` ` ` ` ` `# check length of longest sub-segment ` ` ` `# when greater then previous best ` ` ` `# then change it ` ` ` `if` `(i ` `-` `l ` `+` `1` `>` `=` `end ` `-` `start ` `+` `1` `): ` ` ` `end ` `=` `i ` ` ` `start ` `=` `l ` ` ` ` ` `# print the longest sub-segment ` ` ` `for` `i ` `in` `range` `(start, end ` `+` `1` `): ` ` ` `print` `(a[i], end ` `=` `" "` `) ` ` ` `# Driver Code ` `if` `__name__ ` `=` `=` `"__main__"` `: ` ` ` ` ` `a ` `=` `[ ` `6` `, ` `5` `, ` `1` `, ` `2` `, ` `3` `, ` ` ` `2` `, ` `1` `, ` `4` `, ` `5` `] ` ` ` `n ` `=` `len` `(a) ` ` ` `k ` `=` `3` ` ` `longest(a, n, k) ` ` ` `# This code is contributed ` `# by ChitraNayal ` |

*chevron_right*

*filter_none*

## C#

`// C# program to find longest subarray with ` `// k or less distinct elements. ` `using` `System; ` ` ` `class` `GFG ` `{ ` ` ` `// function to print the longest sub-array ` `static` `void` `longest(` `int` `[]a, ` `int` `n, ` `int` `k) ` `{ ` ` ` `int` `[] freq = ` `new` `int` `[7]; ` ` ` ` ` `int` `start = 0, end = 0, now = 0, l = 0; ` ` ` `for` `(` `int` `i = 0; i < n; i++) ` ` ` `{ ` ` ` ` ` `// mark the element visited ` ` ` `freq[a[i]]++; ` ` ` ` ` `// if its visited first time, then increase ` ` ` `// the counter of distinct elements by 1 ` ` ` `if` `(freq[a[i]] == 1) ` ` ` `now++; ` ` ` ` ` `// When the counter of distinct elements ` ` ` `// increases from k, then reduce it to k ` ` ` `while` `(now > k) ` ` ` `{ ` ` ` ` ` `// from the left, reduce the number of ` ` ` `// time of visit ` ` ` `freq[a[l]]--; ` ` ` ` ` `// if the reduced visited time element ` ` ` `// is not present in further segment ` ` ` `// then decrease the count of distinct ` ` ` `// elements ` ` ` `if` `(freq[a[l]] == 0) ` ` ` `now--; ` ` ` ` ` `// increase the subsegment mark ` ` ` `l++; ` ` ` `} ` ` ` ` ` `// check length of longest sub-segment ` ` ` `// when greater then previous best ` ` ` `// then change it ` ` ` `if` `(i - l + 1 >= end - start + 1) ` ` ` `{ ` ` ` `end = i; ` ` ` `start = l; ` ` ` `} ` ` ` `} ` ` ` ` ` `// print the longest sub-segment ` ` ` `for` `(` `int` `i = start; i <= end; i++) ` ` ` `Console.Write(a[i]+` `" "` `); ` `} ` ` ` `// Driver code ` `public` `static` `void` `Main(String []args) ` `{ ` ` ` `int` `[]a = { 6, 5, 1, 2, 3, 2, 1, 4, 5 }; ` ` ` `int` `n = a.Length; ` ` ` `int` `k = 3; ` ` ` `longest(a, n, k); ` `} ` `} ` ` ` `// This code contributed by Rajput-Ji ` |

*chevron_right*

*filter_none*

**Output:**

1 2 3 2 1

**Time Complexity:** O(n)

This article is contributed by **Striver**. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready.

## Recommended Posts:

- Length of longest subarray in which elements greater than K are more than elements not greater than K
- Longest subarray having count of 1s one more than count of 0s
- Length of longest subarray having only K distinct Prime Numbers
- Longest subarray having average greater than or equal to x
- Longest subarray having average greater than or equal to x | Set-2
- Count number of permutation of an Array having no SubArray of size two or more from original Array
- Element which occurs consecutively in a given subarray more than or equal to K times
- Longest subarray in which absolute difference between any two element is not greater than X
- Longest substring with count of 1s more than 0s
- Longest Subarray having sum of elements atmost 'k'
- Longest subarray with elements having equal modulo K
- Smallest subarray having an element with frequency greater than that of other elements
- Longest subarray in which all elements are greater than K
- Longest subarray with absolute difference between elements less than or equal to K using Heaps
- Longest subarray with difference exactly K between any two distinct values
- First subarray having sum at least half the maximum sum of any subarray of size K
- Given an array of size n and a number k, find all elements that appear more than n/k times
- Remove minimum elements from either side such that 2*min becomes more than max
- Array elements that appear more than once
- Remove elements from the array which appear more than k times