每日一题——6259. 设计内存分配器

75 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第23天,点击查看活动详情


设计内存分配器

给你一个整数 n ,表示下标从 0 开始的内存数组的大小。所有内存单元开始都是空闲的。

请你设计一个具备以下功能的内存分配器:

  1. 分配 一块大小为 size 的连续空闲内存单元并赋 id mID 。
  2. 释放 给定 id mID 对应的所有内存单元。

实现 Allocator 类:

  • Allocator(int n) 使用一个大小为 n 的内存数组初始化 Allocator 对象。
  • int allocate(int size, int mID) 找出大小为 size 个连续空闲内存单元且位于  最左侧 的块,分配并赋 id mID 。返回块的第一个下标。如果不存在这样的块,返回 -1 。
  • int free(int mID) 释放 id mID 对应的所有内存单元。返回释放的内存单元数目。

 

提示:

  • 1 <= n, size, mID <= 1000
  • 最多调用 allocate 和 free 方法 1000 次

思路

首先很容易想到的是使用数组来储存内存的分配情况,数组的值存储内存的分配 ID。

需要分配内存时,从数组的 0 下标开始向后搜索,找到未被占用的内存空间,若可以存放相应长度的内存,就回到可分配的开始位置,将这一段内存标记为 mID。

在释放内存时,可以通过遍历一遍数组来实现,但我采取了另一种方法,使用 HashMap 存放对应 mID 的位置,在需要释放内存时,直接根据 HashMap 的映射找到相应位置,其中使用了 Pair 来存放内存标识的左右位置,将相应位置的标识置 0,最后在 HashMap 中删除该 mID。

题解

class Allocator {
    private int n;
    private int[] arr;
    private Map<Integer, List<Pair<Integer, Integer>>> map;
    

    public Allocator(int n) {
        this.n = n;
        arr = new int[n];
        map = new HashMap<>();
    }
    
    public int allocate(int size, int mID) {
        int left = 0;
        boolean flag = true;
        while(left + size <= n && flag) {
            int right = left + size - 1;
            for(int i = left; i <= right; i++) {
                if(arr[i] != 0) {
                    left = i + 1;
                    break;
                }else if(i == right) {
                    while(i >= left) {
                        arr[i--] = mID;
                    }
                    if(!map.containsKey(mID)) {
                        map.put(mID, new ArrayList<>());
                    }
                    List<Pair<Integer, Integer>> list = map.get(mID);
                    list.add(new Pair<>(left, right));
                    flag = false;
                    break;
                }
            }
        }
        return flag? -1: left;
    }
    
    public int free(int mID) {
        if(!map.containsKey(mID)) {
            return 0;
        }
        List<Pair<Integer, Integer>> list = map.get(mID);
        int cnt = 0;
        for(Pair<Integer, Integer> pair: list) {
            int left = pair.getKey(), right = pair.getValue();
            int index = left;
            while(index <= right) {
                arr[index++] = 0;
                cnt++;
            }
        }
        map.remove(mID);
        return cnt;
    }
}