Longest Subarray with at most K Distinct Integers II in Java (O(n^2) Time Complexity)


Given an array of integers, find the longest subarray that contains at most K distinct integers and return its length.

Example

Input: nums = [1, 2, 1, 2, 3], k = 2
Output: 4
Explanation:the subarray nums[0...3] contains 2 distinct values: [1, 2] and is the longest subarray

Note:

Your algorithm should run in O(n^2) time and use O(n) extra space.


Problem Definition

The problem requires finding the longest subarray within a given array of integers that contains at most K distinct integers. The length of this subarray should be returned.

Input

Output

Constraints

Example

Input: nums = [1, 2, 1, 2, 3], k = 2
Output: 4
Explanation: The subarray nums[0...3] contains 2 distinct values: [1, 2] and is the longest subarray.

Understanding the Problem

The core challenge is to find the longest contiguous subarray with at most K distinct integers. This problem is significant in scenarios where we need to analyze data streams or sequences with constraints on diversity.

Potential pitfalls include misunderstanding the requirement for contiguous subarrays and not efficiently managing the count of distinct integers.

Approach

To solve this problem, we can use a sliding window approach. This method allows us to maintain a window of elements that satisfies the condition of having at most K distinct integers.

Naive Solution

A naive solution would involve checking all possible subarrays and counting the distinct integers in each. This approach is not optimal due to its high time complexity of O(n^3).

Optimized Solution

We can optimize the solution using a sliding window technique combined with a hash map to keep track of the count of distinct integers within the window. This approach ensures that we only traverse the array once, achieving a time complexity of O(n^2).

Algorithm

Here is a step-by-step breakdown of the sliding window approach:

  1. Initialize two pointers, left and right, both set to the start of the array.
  2. Use a hash map to keep track of the count of each integer within the window.
  3. Expand the window by moving the right pointer and updating the hash map.
  4. If the number of distinct integers exceeds K, shrink the window by moving the left pointer until the condition is satisfied.
  5. Keep track of the maximum length of the window that satisfies the condition.

Code Implementation

import java.util.HashMap;

public class LongestSubarrayKDistinct {
    public int lengthOfLongestSubarrayKDistinct(int[] nums, int k) {
        // HashMap to store the count of each integer in the current window
        HashMap<Integer, Integer> countMap = new HashMap<>();
        int left = 0, maxLength = 0;

        // Iterate over the array with the right pointer
        for (int right = 0; right < nums.length; right++) {
            // Add the current element to the count map
            countMap.put(nums[right], countMap.getOrDefault(nums[right], 0) + 1);

            // If the number of distinct integers exceeds k, shrink the window
            while (countMap.size() > k) {
                countMap.put(nums[left], countMap.get(nums[left]) - 1);
                if (countMap.get(nums[left]) == 0) {
                    countMap.remove(nums[left]);
                }
                left++;
            }

            // Update the maximum length of the window
            maxLength = Math.max(maxLength, right - left + 1);
        }

        return maxLength;
    }

    public static void main(String[] args) {
        LongestSubarrayKDistinct solution = new LongestSubarrayKDistinct();
        int[] nums = {1, 2, 1, 2, 3};
        int k = 2;
        System.out.println(solution.lengthOfLongestSubarrayKDistinct(nums, k)); // Output: 4
    }
}

Complexity Analysis

The time complexity of the sliding window approach is O(n^2) because, in the worst case, each element is processed twice (once by the right pointer and once by the left pointer). The space complexity is O(n) due to the hash map used to store the count of integers.

Edge Cases

Consider the following edge cases:

Testing

To test the solution comprehensively, consider the following test cases:

Thinking and Problem-Solving Tips

When approaching such problems, consider the following tips:

Conclusion

In this blog post, we discussed the problem of finding the longest subarray with at most K distinct integers. We explored a sliding window approach to solve the problem efficiently and provided a detailed explanation of the algorithm and its implementation in Java. Understanding and solving such problems is crucial for developing strong problem-solving skills and preparing for technical interviews.

Additional Resources

For further reading and practice, consider the following resources: