CodingMedium78% interview frequency · Last seen 2026-03

Cheapest Menu Combinations

Problem

You are given a restaurant `menu` and a list of requested items `userWants`.


Each menu entry is `[id, price, items]` where:

- `id` is a unique string identifier

- `price` is a decimal price as a string (e.g. `"5.00"`)

- `items` is a comma-separated list of item names on that entry (no required spaces)


Implement class `Solution`:

- `Solution()` Initialize the solver (no arguments).

- `string[][] getCheapestCombinations(string[][] menu, string[] userWants)` Return every unique combination of menu entry IDs that covers **all** items in `userWants` at the **minimum total cost**.


Rules:

- Extra items on a menu entry may be ignored.

- A combination is a set of menu IDs (order of selection does not matter).

- Within each combination, return IDs in ascending lexicographic order.

- Return the list of combinations sorted lexicographically (compare ID lists left-to-right).

- If the order cannot be fulfilled, return an empty list `[]`.


Constraints:

- `1 <= menu.length <= 15`

- `1 <= userWants.length <= 15`

- Menu IDs are unique; prices are positive.

- Item names are non-empty strings; `userWants` may contain duplicates (treat as a set of required items).


Example:


```

menu = [

["1", "5.00", "pizza"],

["2", "8.00", "sandwich,coke"],

["3", "4.00", "pasta"],

["4", "2.00", "coke"],

["5", "6.00", "pasta,coke,pizza"],

["6", "8.00", "burger,coke,pizza"],

["7", "5.00", "sandwich"]

]

userWants = ["sandwich", "pasta", "coke"]

```


Output: `[["3", "4", "7"], ["5", "7"]]`


Both combinations cost `11.00`. IDs `3+4+7` cover pasta, coke, and sandwich; IDs `5+7` also cover every requested item (extra pizza ignored).

Common follow-ups

  • How would you scale this if menu.length is hundreds instead of ~15?
  • What if prices can be zero or negative promotional discounts?
  • How would you rank ties by fewest menu entries instead of listing all min-cost combinations?
  • How would you support quantity constraints (need two sandwiches)?

Step-by-step study guide

Step 1: Clarify

You must cover every distinct item in `userWants`. Menu entries can over-deliver items. Among all covering subsets of the menu, keep only those with the smallest summed price, then return their ID sets in a canonical sorted form.

Ask: Are IDs always unique? Can the same item appear on many dishes? Is `userWants` a multiset or a set? (Here: set of required items.)

Step 2: Trace the example

Required: sandwich, pasta, coke.

Useful dishes (those that contribute at least one required item):

| ID | Price | Covers | |----|-------|--------| | 2 | 8 | sandwich, coke | | 3 | 4 | pasta | | 4 | 2 | coke | | 5 | 6 | pasta, coke | | 6 | 8 | coke | | 7 | 5 | sandwich |

Min-cost covers at 11: `{3,4,7}` and `{5,7}`. Dish 1 (pizza only) never helps.

Step 3: Brute force

Enumerate all `2^n` subsets of menu entries (`n <= 15`). For each subset, compute the union of items and total cost. Track the minimum cost and collect matching ID lists. Sort for the required output order.

Step 4: Speed up with bitmasks

Map each distinct wanted item to a bit. Convert every dish to `(id, price, mask)`. A subset is valid when OR of masks equals the full mask. Comparing costs with money: use floats carefully or work in integer cents.

Optional DP: `dp[mask] = min cost to achieve coverage mask`, plus store predecessor/lists of ways — useful when you only need one answer, heavier when you need all min-cost combinations.

Step 5: Implement carefully

  • Skip dishes whose mask is 0 (no overlap with `userWants`).
  • Deduplicate combinations (same ID set found once).
  • Sort each ID list, then sort the list of lists.
  • Impossible → `[]`.

Step 6: Complexity

  • Time: `O(2^n * n)` for subset enumeration with `n = menu.length` (after filtering irrelevant dishes).
  • Space: `O(n + number of answers)`.

Step 7: Follow-ups

For larger `n`, use meet-in-the-middle, branch-and-bound on cost, or integer-linear / set-cover heuristics. For quantities, expand bits or use a count vector instead of a bitmask.

Practice

Sign in to unlock practice

Create a free account for full access through 2027 — study guides, follow-ups, and an in-browser code editor. Part of our AI bubble promotion; feedback is appreciated.