def subarrays_exactly_k(nums, k):
    def at_most(limit):
        if limit <= 0:
            return 0
        counts = {}
        left = total = 0
        for right, value in enumerate(nums):
            counts[value] = counts.get(value, 0) + 1
            while len(counts) > limit:
                old = nums[left]
                counts[old] -= 1
                if counts[old] == 0:
                    del counts[old]
                left += 1
            total += right - left + 1
        return total
    return 0 if k <= 0 else at_most(k) - at_most(k - 1)
