Maximize tokens from nested crates
Company: Airbnb
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: Medium
Interview Round: Onsite
Quick Answer: This question evaluates proficiency with graph-based algorithms, state management, and data structure selection for handling dependencies, cycles, duplicates, and dynamic discovery in resource-collection scenarios.
Constraints
- 0 <= n <= 100000
- len(status) == len(tokens) == len(keys) == len(contained_crates) == n
- 0 <= tokens[i] <= 10^9
- 0 <= each crate index in keys, contained_crates, and initial_crates < n
- The total number of entries across all keys lists and contained_crates lists is at most 200000
- Duplicates and cycles are allowed
Examples
Input: ([1,0,0,0], [5,10,20,1], [[1], [2], [3], []], [[1], [2], [3], []], [0])
Expected Output: 36
Explanation: Open crate 0, then 1, then 2, then 3. The total is 5 + 10 + 20 + 1 = 36.
Input: ([1,0,1,0], [7,5,4,9], [[], [3], [1], []], [[1,2], [3], [], []], [0])
Expected Output: 25
Explanation: Crate 1 is discovered first but stays locked. Crate 2 is accessible and unlocked, and opening it gives the key to crate 1. Then opening crate 1 reveals crate 3, which is already unlocked by its key. Total = 7 + 4 + 5 + 9 = 25.
Input: ([1,0,0], [2,3,4], [[1,1], [2], [0]], [[1,1], [2,0], [1]], [0,0])
Expected Output: 9
Explanation: Duplicates and cycles do not change the result because each crate is opened at most once. All three crates become openable, so the total is 2 + 3 + 4 = 9.
Input: ([0,0], [5,6], [[1], []], [[1], []], [0])
Expected Output: 0
Explanation: Crate 0 is accessible but locked, and no other crate can be opened to obtain its key. Therefore no tokens can be collected.
Input: ([], [], [], [], [])
Expected Output: 0
Explanation: There are no crates, so the answer is 0.
Solution
def solution(status, tokens, keys, contained_crates, initial_crates):
from collections import deque
n = len(status)
unlocked = [s == 1 for s in status]
accessible = [False] * n
opened = [False] * n
queue = deque()
for crate in initial_crates:
if not accessible[crate]:
accessible[crate] = True
if unlocked[crate]:
queue.append(crate)
total = 0
while queue:
crate = queue.popleft()
if opened[crate] or not accessible[crate] or not unlocked[crate]:
continue
opened[crate] = True
total += tokens[crate]
for key in keys[crate]:
if not unlocked[key]:
unlocked[key] = True
if accessible[key] and not opened[key]:
queue.append(key)
for nxt in contained_crates[crate]:
if not accessible[nxt]:
accessible[nxt] = True
if unlocked[nxt] and not opened[nxt]:
queue.append(nxt)
return totalTime complexity: O(n + E), where E is the total number of entries across all keys and contained_crates lists. Space complexity: O(n).
Hints
- A crate becomes openable only when two conditions are true at the same time: it is accessible and it is unlocked. Track these states separately.
- Use a queue for crates that are ready to open. Opening one crate can unlock previously discovered crates or make previously unlocked crates newly accessible.