1833. Maximum Ice Cream Bars

  • Array
  • Greedy
  • Sorting
  • Counting Sort
TIME
O(n + m)
SPACE
O(m)
problem on leetcode ↗source on github ↗

Intuition

To maximize count, buy cheapest items first. Use counting sort to efficiently process items by cost in ascending order without explicit sorting.

Solution

  1. Build frequency array: Count how many ice creams exist at each price point.

  2. Iterate from cheapest: Process costs from 1 to maxCost.

  3. Buy greedily:

    • If we can afford all items at current cost: buy all, subtract total cost
    • If we can't afford all: buy as many as possible (coins / cost), then stop
  4. Return count: Total number of ice creams purchased.

Why Counting Sort?

  • Problem explicitly requires counting sort
  • Efficient when cost range is bounded: O(n + maxCost)
  • Avoids O(n log n) comparison sort

Complexity

  • Time: O(n + m) where n = number of items, m = max cost
  • Space: O(m), frequency array

Edge Cases

  • Can't afford any → return 0
  • Can afford all → return n
  • Large coins value → use long in Java to prevent overflow on cost * frequency

Code

from typing import List


class Solution:
    def maxIceCream(self, costs: List[int], coins: int) -> int:
        """
        1833. Maximum Ice Cream Bars
        Time: O(n + m)
        Space: O(m)
        """
        max_cost = max(costs)
        frequency = [0] * (max_cost + 1)
        for cost in costs:
            frequency[cost] += 1

        answer = 0

        for cost in range(1, max_cost + 1):
            total_cost = cost * frequency[cost]
            if coins >= total_cost:
                coins -= total_cost
                answer += frequency[cost]
            else:
                answer += coins // cost
                break

        return answer