04. Subarrays With At Most K Distinct Integers

βœ… GFG solution to the Subarrays With At Most K Distinct Integers problem: count subarrays containing at most k distinct elements using sliding window technique. πŸš€

The problem can be found at the following link: πŸ”— Question Link

🧩 Problem Description

You are given an array arr[] of positive integers and an integer k. Your task is to find the number of subarrays in arr[] where the count of distinct integers is at most k.

A subarray is a contiguous part of an array. The goal is to efficiently count all valid subarrays without generating them explicitly.

πŸ“˜ Examples

Example 1

Input: arr[] = [1, 2, 2, 3], k = 2
Output: 9
Explanation: Subarrays with at most 2 distinct elements are: [1], [2], [2], [3], [1, 2], [2, 2], [2, 3], [1, 2, 2] and [2, 2, 3].

Example 2

Input: arr[] = [1, 1, 1], k = 1
Output: 6
Explanation: Subarrays with at most 1 distinct element are: [1], [1], [1], [1, 1], [1, 1] and [1, 1, 1].

Example 3

πŸ”’ Constraints

  • $1 \le \text{arr.size()} \le 2 \times 10^4$

  • $1 \le k \le 2 \times 10^4$

  • $1 \le \text{arr}[i] \le 10^9$

βœ… My Approach

The optimal approach uses the Sliding Window technique with a Hash Map to efficiently count subarrays with at most k distinct elements:

Sliding Window + Hash Map

  1. Initialize Variables:

    • Use two pointers: left (start of window) and right (end of window).

    • Maintain a hash map to store frequency of elements in current window.

    • Use a counter to track distinct elements efficiently.

  2. Expand Window:

    • Move right pointer and add arr[right] to the hash map.

    • If it's a new element (frequency becomes 1), decrement k.

  3. Contract Window:

    • If k becomes negative (more than k distinct elements), shrink window from left.

    • Remove arr[left] from frequency map and increment k if element is completely removed.

    • Move left pointer forward.

  4. Count Subarrays:

    • For each valid window ending at right, add (right - left + 1) to result.

    • This counts all subarrays ending at right with at most k distinct elements.

  5. Continue Until End:

    • Repeat until right pointer reaches the end of array.

πŸ“ Time and Auxiliary Space Complexity

  • Expected Time Complexity: O(n), where n is the size of the array. Each element is visited at most twice by the sliding window pointers, making it linear time.

  • Expected Auxiliary Space Complexity: O(k), where k is the maximum number of distinct elements allowed. In the worst case, the hash map stores at most k distinct elements with their frequencies.

πŸ§‘β€πŸ’» Code (C++)

⚑ View Alternative Approaches with Code and Analysis

πŸ“Š 2️⃣ Array-Based Approach (For Limited Range)

πŸ’‘ Algorithm Steps:

  1. Use a fixed-size array to track frequency when the range of elements is known

  2. Maintain a count of distinct elements in the current window

  3. Expand window by moving right pointer and shrink when necessary

  4. Add valid subarray count for each position

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n + maxVal)

  • Auxiliary Space: πŸ’Ύ O(maxVal) - for frequency array

βœ… Why This Approach?

  • Faster access times with array indexing

  • No hash collisions

  • Better cache locality

πŸ“Š 3️⃣ Two-Pointer with Set Approach

πŸ’‘ Algorithm Steps:

  1. Use an unordered_set to track distinct elements

  2. Use an unordered_map to maintain frequencies

  3. Expand and contract window based on distinct count

  4. Calculate subarray count for each valid window

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n)

  • Auxiliary Space: πŸ’Ύ O(k) - for set and map

βœ… Why This Approach?

  • Clear separation of concerns

  • Easy to understand logic

  • Explicit distinct element tracking

πŸ“Š 4️⃣ Optimized Single Map Approach

πŸ’‘ Algorithm Steps:

  1. Use only one unordered_map to track both frequency and distinct count

  2. Increment/decrement distinct count based on frequency changes

  3. Maintain sliding window with efficient contraction

  4. Calculate result in single pass

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n)

  • Auxiliary Space: πŸ’Ύ O(k) - for map storage

βœ… Why This Approach?

  • Memory efficient with single data structure

  • Clean and concise implementation

  • Automatic distinct count via map size

πŸ“Š 5️⃣ Frequency Counter Optimization

πŸ’‘ Algorithm Steps:

  1. Use a frequency counter variable to track distinct elements without using map size

  2. Maintain frequency map for element counts

  3. Efficiently update counter when elements are added/removed

  4. Single pass solution with optimal space usage

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n)

  • Auxiliary Space: πŸ’Ύ O(k) - for frequency map

βœ… Why This Approach?

  • Avoids repeated map.size() calls

  • Explicit control over distinct count

  • Cleaner logic flow

πŸ†š πŸ” Comparison of Approaches

πŸš€ Approach

⏱️ Time Complexity

πŸ’Ύ Space Complexity

βœ… Pros

⚠️ Cons

πŸ” HashMap Sliding Window

🟒 O(n)

🟑 O(k)

πŸš€ Works with any values

πŸ’Ύ HashMap overhead

πŸ”„ Array-Based Approach

🟒 O(n)

🟑 O(maxVal)

⚑ Fastest access, no collisions

πŸ“ Limited to known range

πŸ”Ί Two-Pointer with Set

🟒 O(n)

🟑 O(k)

πŸ”§ Clear logic, explicit tracking

πŸ’Ύ Extra space for set

⏰ Single Map Approach

🟒 O(n)

🟑 O(k)

πŸš€ Memory efficient, clean code

πŸ”„ Map erase operations

πŸ“Š Frequency Counter

🟒 O(n)

🟑 O(k)

⚑ Avoids size() calls, optimal

πŸ”§ Slightly more complex counter

πŸ† Best Choice Recommendation

🎯 Scenario

πŸŽ–οΈ Recommended Approach

πŸ”₯ Performance Rating

⚑ Maximum performance, known element range

πŸ₯‡ Array-Based Approach

β˜…β˜…β˜…β˜…β˜…

πŸ”§ General purpose, any integer values

πŸ₯ˆ HashMap Sliding Window

β˜…β˜…β˜…β˜…β˜†

πŸ“Š Memory constrained environments

πŸ₯‰ Single Map Approach

β˜…β˜…β˜…β˜…β˜†

🎯 Educational purposes, clear logic

πŸŽ–οΈ Two-Pointer with Set

β˜…β˜…β˜…β˜†β˜†

πŸš€ Optimal performance, competitive programming

πŸ… Frequency Counter

β˜…β˜…β˜…β˜…β˜…

πŸ§‘β€πŸ’» Code (Java)

🐍 Code (Python)

🧠 Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: πŸ“¬ Any Questions?. Let's make this learning journey more collaborative!

⭐ If you find this helpful, please give this repository a star! ⭐


πŸ“Visitor Count

Visitor counter

Last updated