Minimum Stores for a Shopping List
Reported by candidates from WhatNot's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
WhatNot reportedly put this one in front of candidates in September 2026, and the constraints are the whole story. Up to 50 stores, up to 20 distinct items. That's a minimum set cover problem, and trying every subset of stores means 2^50, which won't finish. The small item count is the hint. Think bitmasks over the shopping list, not over the stores. If you're taking this OA soon, learn the mask DP below. StealthCoder is the safety net if your mind goes blank mid-assessment, but this is a pattern you can lock in tonight.
The problem
You have a shopping list and a collection of stores. Each store carries a set of items. Return the minimum number of distinct stores you must visit so that every item on the shopping list can be purchased. An item may be purchased from any visited store that carries it. Duplicate names in the shopping list represent the same required item. Return -1 when at least one required item cannot be covered. Function minimumStores(stores: String[][], shoppingList: String[]) → int Examples Example 1 stores = [["milk","bread"],["eggs"],["bread","eggs"]] shoppingList = ["milk","eggs"] return = 2 No single store carries both required items, so two visits are necessary. Example 2 stores = [["apple","tea"],["tea","rice","apple"],["rice"]] shoppingList = ["apple","rice","tea"] return = 1 The second store covers the entire list. Example 3 stores = [["a"],["b"]] shoppingList = ["a","c"] return = -1 No store carries c. Constraints 0 <= stores.length <= 50. 0 <= shoppingList.length <= 20. Every item name is a non-empty case-sensitive ASCII string of length at most 40. Repeated item names within a store do not change its coverage.
Reported by candidates. Source: FastPrep
Pattern and pitfall
Dedupe the shopping list first and map each unique item to a bit index, so you have at most 20 bits. Convert each store into a mask of the needed items it carries, ignoring everything else. Then run DP over masks: dp[mask] is the fewest stores needed to cover exactly that set, starting with dp[0] = 0. For each mask and each store, update dp[mask | storeMask] = min(dp[mask] + 1). That's about 2^20 times 50 operations, which is fine. Answer is dp[full], or -1 if it's unreachable, which also handles the missing-item case. Pitfalls: forgetting duplicates in the list, so the full mask is wrong. Also an empty shopping list should return 0, even with no stores. Skipping stores with a zero mask saves work. If you freeze on the live OA, StealthCoder can hand you this DP so you can check it against your own reasoning.
Memorize the pattern. If you can't, run StealthCoder. The proctor sees the IDE. They don't see what's behind it.
You can drill Minimum Stores for a Shopping List cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Made by an engineer who treats the OA as theater. If yours is tonight, you don't have time to grind. You have time to hedge.
Get StealthCoderRelated leaked OAs
This OA pattern shows up on LeetCode as smallest sufficient team. If you have time before the OA, drill that.
You've seen the question.
Make sure you actually pass WhatNot's OA.
WhatNot reuses patterns across OAs. Made by an engineer who treats the OA as theater. If yours is tonight, you don't have time to grind. You have time to hedge. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Minimum Stores for a Shopping List FAQ
What's the trick in the WhatNot Minimum Stores problem?+
Don't enumerate store subsets. Map the unique shopping list items to bits, turn each store into a bitmask, and run a DP over covered-item masks. With at most 20 items, 2^20 states times 50 stores is easily fast enough.
Why does brute force fail here?+
With up to 50 stores, trying every subset is 2^50 combinations. That's far too many. Greedy picking the store covering the most items also fails, since set cover isn't solved by greedy in general. The 20-item cap points at bitmask DP.
What edge cases should I test?+
Empty shopping list should return 0. An item that no store carries returns -1. Duplicate names in the list count once. Repeated items inside a store don't matter. Zero stores with a non-empty list returns -1. Names are case-sensitive, so Milk and milk differ.
How hard is this really?+
Medium to hard if you haven't seen bitmask DP, easy once you have. The code is short: build masks, fill a dp array, loop over stores. The difficulty is spotting the pattern from the constraints, not writing it.
How do I prepare for this in 48 hours?+
Write the solution once from scratch without looking. Practice mapping strings to bit indices and building masks. Then run the three examples by hand. Also test the empty list and the impossible case, since those are where most wrong answers come from.