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:
Initialization:
Counter
in Python, HashMap
in Java/C++/Rust, Map
in TypeScript) to store the frequency of each candy flavor.k
to the end of the candies
array. This represents the candies you keep initially.ans
) based on the size of the hash table.Sliding Window:
candies
array using a sliding window of size k
.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).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.