给你一个整数 n
,表示下标从 0 开始的内存数组的大小。所有内存单元开始都是空闲的。
请你设计一个具备以下功能的内存分配器:
- 分配 一块大小为
size
的连续空闲内存单元并赋 idmID
。 - 释放 给定 id
mID
对应的所有内存单元。
注意:
- 多个块可以被分配到同一个
mID
。 - 你必须释放
mID
对应的所有内存单元,即便这些内存单元被分配在不同的块中。
实现 Allocator
类:
Allocator(int n)
使用一个大小为n
的内存数组初始化Allocator
对象。int allocate(int size, int mID)
找出大小为size
个连续空闲内存单元且位于 最左侧 的块,分配并赋 idmID
。返回块的第一个下标。如果不存在这样的块,返回-1
。int freeMemory(int mID)
释放 idmID
对应的所有内存单元。返回释放的内存单元数目。
示例:
输入 ["Allocator", "allocate", "allocate", "allocate", "freeMemory", "allocate", "allocate", "allocate", "freeMemory", "allocate", "freeMemory"] [[10], [1, 1], [1, 2], [1, 3], [2], [3, 4], [1, 1], [1, 1], [1], [10, 2], [7]] 输出 [null, 0, 1, 2, 1, 3, 1, 6, 3, -1, 0]解释 Allocator loc = new Allocator(10); // 初始化一个大小为 10 的内存数组,所有内存单元都是空闲的。 loc.allocate(1, 1); // 最左侧的块的第一个下标是 0 。内存数组变为 [1, , , , , , , , , ]。返回 0 。 loc.allocate(1, 2); // 最左侧的块的第一个下标是 1 。内存数组变为 [1,2, , , , , , , , ]。返回 1 。 loc.allocate(1, 3); // 最左侧的块的第一个下标是 2 。内存数组变为 [1,2,3, , , , , , , ]。返回 2 。 loc.freeMemory(2); // 释放 mID 为 2 的所有内存单元。内存数组变为 [1, ,3, , , , , , , ] 。返回 1 ,因为只有 1 个 mID 为 2 的内存单元。 loc.allocate(3, 4); // 最左侧的块的第一个下标是 3 。内存数组变为 [1, ,3,4,4,4, , , , ]。返回 3 。 loc.allocate(1, 1); // 最左侧的块的第一个下标是 1 。内存数组变为 [1,1,3,4,4,4, , , , ]。返回 1 。 loc.allocate(1, 1); // 最左侧的块的第一个下标是 6 。内存数组变为 [1,1,3,4,4,4,1, , , ]。返回 6 。 loc.freeMemory(1); // 释放 mID 为 1 的所有内存单元。内存数组变为 [ , ,3,4,4,4, , , , ] 。返回 3 ,因为有 3 个 mID 为 1 的内存单元。 loc.allocate(10, 2); // 无法找出长度为 10 个连续空闲内存单元的空闲块,所有返回 -1 。 loc.freeMemory(7); // 释放 mID 为 7 的所有内存单元。内存数组保持原状,因为不存在 mID 为 7 的内存单元。返回 0 。
提示:
1 <= n, size, mID <= 1000
- 最多调用
allocate
和free
方法1000
次
分析:直接模拟即可。实现int allocate(int size, int mID)
函数时,每次从最初的位置开始查询是否空闲,并记录连续空闲空间的个数。如果某个位置已经分配,则将当前的连续空间计数重置为0.当连续空闲空间计数为size时,说明可以分配,起点位于当前位置的前size处。
typedef struct {int n;int *memory;
} Allocator;Allocator* allocatorCreate(int n) {Allocator *p=(Allocator*)malloc(sizeof(Allocator));p->n=n;p->memory=(int*)malloc(sizeof(int)*n);for(int i=0;i<n;++i)p->memory[i]=0;return p;
}int allocatorAllocate(Allocator* obj, int size, int mID) {int n=obj->n,cnt=0;for(int i=0;i<n;++i){if(obj->memory[i]==0)cnt++;else cnt=0;if(cnt==size){for(int j=i-cnt+1;j<=i;++j)obj->memory[j]=mID;return i-cnt+1;}}return -1;
}int allocatorFreeMemory(Allocator* obj, int mID) {int n=obj->n,cnt=0;for(int i=0;i<n;++i)if(obj->memory[i]==mID)cnt++,obj->memory[i]=0;return cnt;
}void allocatorFree(Allocator* obj) {free(obj->memory);free(obj);return;
}/*** Your Allocator struct will be instantiated and called as such:* Allocator* obj = allocatorCreate(n);* int param_1 = allocatorAllocate(obj, size, mID);* int param_2 = allocatorFreeMemory(obj, mID);* allocatorFree(obj);
*/