Design and implement a dynamic memory allocator that manages a contiguous block of memory. Think of it like managing RAM in an operating system - you need to efficiently allocate blocks of memory to different processes and free them when they're no longer needed.
You're given an integer n representing the size of a 0-indexed memory array. Initially, all memory units are free (available for allocation).
Your memory allocator must support these operations:
- Allocate: Find the leftmost block of consecutive free memory units of a given size and assign it a memory ID (mID)
- Free: Release all memory units associated with a given memory ID
Key constraints:
- Multiple separate blocks can be allocated to the same mID
- When freeing memory, you must free ALL units with that mID, regardless of how they were allocated
- Always allocate to the leftmost available position to minimize fragmentation
Input & Output
Visualization
Time & Space Complexity
Allocation scans up to n positions, freeing takes O(k) where k is number of units to free
Memory array O(n) plus hash map storing up to n positions across m different mIDs
Constraints
- 1 โค n, size โค 1000
- 1 โค mID โค 1000
- At most 1000 calls will be made to allocate and freeMemory
- Memory positions are 0-indexed