Implement Grid Spread and Transactional Store
Company: Lyft
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: hard
Interview Round: Onsite
Quick Answer: This question evaluates skills in grid-based propagation modeling and stateful transactional system design, testing concepts such as graph traversal and timed spread dynamics for the grid task and nested transaction semantics, isolation, and state management for the in-memory key-value store.
Part 1: Compute Contamination Spread Time
Constraints
- `0 <= m, n <= 200`, where `m` is the number of rows and `n` is the number of columns
- Each `grid[r][c]` is one of `0`, `1`, or `2`
- Contamination spreads only in 4 directions
Examples
Input: [[2, 1, 1], [1, 1, 0], [0, 1, 1]]
Expected Output: 4
Explanation: The contamination spreads outward level by level and reaches the last fresh item after 4 minutes.
Input: [[2, 1, 1], [0, 1, 1], [1, 0, 1]]
Expected Output: -1
Explanation: The fresh item at the bottom-left is isolated by empty cells, so not all fresh items can be contaminated.
Input: [[0, 2, 0]]
Expected Output: 0
Explanation: There are no fresh items, so no time is needed.
Input: []
Expected Output: 0
Explanation: An empty grid has nothing to process.
Input: [[2, 1, 1], [1, 1, 1], [0, 2, 1]]
Expected Output: 2
Explanation: There are two initial contamination sources, so the spread finishes faster.
Hints
- Think of all initially contaminated cells as starting points at the same time.
- A breadth-first search by levels naturally models the minute-by-minute spread.
Part 2: Implement an In-Memory Transactional Key-Value Store
Constraints
- `1 <= len(operations) <= 10^4`
- Transaction nesting depth can be as large as the number of operations
- Keys are strings and values are integers in the provided tests
- Deleting a missing key should not raise an error
Examples
Input: [('set', 'a', 10), ('get', 'a'), ('delete', 'a'), ('get', 'a')]
Expected Output: [10, None]
Explanation: Basic operations outside a transaction work directly on the main store.
Input: [('rollback',), ('commit',)]
Expected Output: [False, False]
Explanation: Both commands fail because there is no active transaction.
Input: [('set', 'x', 1), ('begin',), ('delete', 'x'), ('get', 'x'), ('rollback',), ('get', 'x')]
Expected Output: [None, True, 1]
Explanation: Inside the transaction, `x` appears deleted. After rollback, the original value is visible again.
Input: [('begin',), ('set', 'a', 1), ('begin',), ('get', 'a'), ('rollback',), ('get', 'a'), ('commit',), ('get', 'a')]
Expected Output: [1, True, 1, True, 1]
Explanation: The inner transaction can read a value changed in the outer transaction. Rolling back the inner one does not affect the outer change.
Input: [('set', 'x', 5), ('begin',), ('delete', 'x'), ('set', 'x', 7), ('begin',), ('set', 'x', 9), ('rollback',), ('get', 'x'), ('commit',), ('get', 'x')]
Expected Output: [True, 7, True, 7]
Explanation: A key deleted and then set again in the same transaction should hold the new value. Rolling back the inner transaction restores the outer transaction's state.
Hints
- Use a stack to represent nested transactions.
- For reads, search from the most recent transaction backward before checking the main store.