Implement a Contiguous Memory Manager
Company: OpenAI
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: hard
Interview Round: Technical Screen
Quick Answer: This question evaluates competence in designing efficient data structures and algorithms for interval management, contiguous allocation and deallocation over large sparse arrays, emphasizing complexity analysis and handling of large address spaces.
Constraints
- 1 <= n <= 10^9
- 0 <= len(operations) <= 2 * 10^5
- For an allocate operation, 1 <= size <= n and 1 <= mID <= 10^9
- For a free operation, 1 <= mID <= 10^9
- An O(n) memory array solution is not acceptable for the largest tests
Examples
Input: (10, [('allocate', 3, 1), ('allocate', 2, 2), ('free', 1), ('allocate', 4, 3), ('allocate', 1, 4), ('free', 2), ('allocate', 3, 5)])
Expected Output: [0, 3, 3, 5, 0, 2, 1]
Explanation: After the first two allocations, freeing mID 1 releases cells [0..2]. The allocation of size 4 must skip that block and use the free block starting at 5. Later, freeing mID 2 merges with the adjacent free block on its left, allowing the final allocation to start at index 1.
Input: (5, [('free', 7), ('allocate', 5, 1), ('allocate', 1, 2), ('free', 1), ('allocate', 2, 3)])
Expected Output: [0, 0, -1, 5, 0]
Explanation: Freeing a non-existent mID releases 0 cells. Allocating size 5 uses the whole memory, so the next allocation fails. Freeing mID 1 restores all 5 cells, and the final allocation starts at 0.
Input: (12, [('allocate', 2, 1), ('allocate', 3, 2), ('allocate', 2, 1), ('free', 1), ('allocate', 4, 3), ('free', 2), ('allocate', 5, 4), ('free', 3), ('free', 4)])
Expected Output: [0, 2, 5, 4, 5, 3, 0, 4, 5]
Explanation: mID 1 owns two separate blocks, so freeing it releases 4 cells total. Later frees trigger merges with neighboring free intervals, eventually rebuilding the entire memory into one free block.
Input: (1, [('allocate', 1, 1), ('free', 1), ('allocate', 1, 2), ('free', 3)])
Expected Output: [0, 1, 0, 0]
Explanation: This checks the single-cell boundary case. The one cell can be allocated and freed correctly, and freeing an ID that is not present returns 0.
Input: (8, [])
Expected Output: []
Explanation: With no operations, there are no results to return.
Hints
- Think in terms of intervals instead of individual cells. Allocation splits one free interval, and freeing only needs to check the immediate left and right neighbors for possible merges.
- To avoid scanning all free blocks on every allocation, keep free intervals ordered by start position and store the maximum free-block length in each subtree so you can find the leftmost valid interval quickly.