{x}
blog image

Number of Unique Flavors After Sharing K Candies

Solution Explanation: Number of Unique Flavors After Sharing K Candies

This problem can be efficiently solved using a sliding window approach combined with a hash table (or dictionary). The goal is to find the maximum number of unique candy flavors you can keep after giving away k consecutive candies to your sister.

Algorithm:

  1. Initialization:

    • Create a hash table (e.g., Counter in Python, HashMap in Java/C++/Rust, Map in TypeScript) to store the frequency of each candy flavor.
    • Initially, populate the hash table with the candy flavors from index k to the end of the candies array. This represents the candies you keep initially.
    • Calculate the initial number of unique flavors (ans) based on the size of the hash table.
  2. Sliding Window:

    • Iterate through the candies array using a sliding window of size k.
    • In each iteration:
      • Add: Increment the count of the candy flavor at the rightmost position of the window (the candy you're adding back into your collection after giving some to your sister).
      • Remove: Decrement the count of the candy flavor at the leftmost position of the window (the candy moving out of your 'kept' set). If the count becomes 0, remove the flavor from the hash table.
      • Update ans: Update ans to be the maximum of the current ans and the size of the hash table (representing the unique flavors you currently keep).
  3. Return ans: After iterating through all candies, ans holds the maximum number of unique candy flavors you could keep.

Time Complexity: O(n), where n is the length of the candies array. We iterate through the array once using the sliding window. Hash table operations (insertion, deletion, lookup) are on average O(1).

Space Complexity: O(m), where m is the number of unique candy flavors. In the worst case, this could be equal to n if all candies have unique flavors. However, in many practical scenarios, m will be much smaller than n.

Code Examples (with explanations):

Python:

from collections import Counter
 
class Solution:
    def shareCandies(self, candies: List[int], k: int) -> int:
        n = len(candies)
        cnt = Counter(candies[k:])  # Initialize with candies we keep initially
        ans = len(cnt)  # Initial unique flavor count
 
        for i in range(k, n):
            cnt[candies[i - k]] += 1  # Add candy back (right side of window)
            cnt[candies[i]] -= 1      # Remove candy (left side of window)
            if cnt[candies[i]] == 0:
                del cnt[candies[i]]  # Remove from hash table if count becomes 0
            ans = max(ans, len(cnt))  # Update max unique flavors
 
        return ans

Java:

import java.util.*;
 
class Solution {
    public int shareCandies(int[] candies, int k) {
        int n = candies.length;
        Map<Integer, Integer> cnt = new HashMap<>();
        for (int i = k; i < n; ++i) {
            cnt.put(candies[i], cnt.getOrDefault(candies[i], 0) + 1);
        }
        int ans = cnt.size();
 
        for (int i = k; i < n; ++i) {
            cnt.put(candies[i - k], cnt.get(candies[i - k]) + 1);
            cnt.put(candies[i], cnt.get(candies[i]) - 1);
            if (cnt.get(candies[i]) == 0) {
                cnt.remove(candies[i]);
            }
            ans = Math.max(ans, cnt.size());
        }
        return ans;
    }
}

The other languages (C++, Go, TypeScript, Rust) follow a very similar pattern using their respective hash table implementations. The core logic of the sliding window and hash table manipulation remains consistent across all examples.