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:

- Longest subarray with difference exactly K between any two distinct values
- Distinct elements in subarray using Mo's Algorithm
- Queries for number of distinct elements in a subarray | Set 2
- Longest subarray with all elements same
- Longest subarray in which all elements are greater than K
- Length of the longest Subarray with only Even Elements
- Longest Subarray having sum of elements atmost 'k'
- Longest subarray with elements having equal modulo K
- Longest subarray such that adjacent elements have at least one common digit | Set 1
- Longest subarray such that adjacent elements have at least one common digit | Set - 2
- Length of longest Subarray with equal number of odd and even elements
- Length of Longest Subarray with same elements in atmost K increments
- Longest subarray whose elements can be made equal by maximum K increments
- Longest subarray with absolute difference between elements less than or equal to K using Heaps
- Length of longest subarray in which elements greater than K are more than elements not greater than K
- Maximum length of subarray such that all elements are equal in the subarray
- Maximize the subarray sum after multiplying all elements of any subarray with X
- Smallest subarray with k distinct numbers
- Longest subarray having sum K | Set 2
- Longest subarray with only one value greater than k