java - 为特定键分配和取消分配数字

标签 java algorithm data-structures

我正在处理以下面试问题:

有一个 Allocator 类,其中我有两个方法 allocatedeallocate

class Allocator {
    int allocate(String key);
    boolean deallocate(String key, int number); 
}
  • allocate 方法会将以 0 开头的数字分配给特定的键。如果我们再次分配相同的 key ,则增加最后使用的数字。
  • deallocate 方法将为该特定键解除分配该数字。在为特定 key 释放该号码后,如果我们再次分配相同的 key ,那么我们应该使用当前 key 不可用的 key 。

例如:

 allocate("foo") -> 0
 allocate("foo") -> 1
 allocate("bar") -> 0
 allocate("foo") -> 2
 allocate("foo") -> 3
 allocate("foo") -> 4

 deallocate("foo", 2)

 allocate("foo") -> 2
 allocate("foo") -> 5

下面是我得到的,它可以工作,但我认为时间复杂度可能不适合分配和解除分配。有没有更好、更有效的方法来做到这一点?

public class Allocator {
  private static final Map<String, List<Integer>> cmap = new HashMap<>();
  private static final Map<String, List<Integer>> umap = new HashMap<>();

  public static void main(String[] args) {
    Allocator na = new Allocator();
    System.out.println(na.allocate("foo"));
    System.out.println(na.allocate("foo"));
    System.out.println(na.allocate("bar"));
    System.out.println(na.allocate("foo"));
    System.out.println(na.allocate("foo"));
    System.out.println(na.allocate("foo"));

    System.out.println(na.deallocate("foo", 2));
    System.out.println(na.allocate("foo"));
    System.out.println(na.allocate("foo"));
  }

  public int allocate(String key) {
    if (umap.containsKey(key)) {
      List<Integer> l = umap.get(key);
      if (!l.isEmpty()) {
        int val = l.remove(0);
        List<Integer> currentList = cmap.get(key);
        if (currentList == null) {
          currentList = new ArrayList<>();
          currentList.add(val);
          cmap.put(key, currentList);
          return val;
        }
        currentList.add(val);
        Collections.sort(currentList);
        cmap.put(key, currentList);
        return val;
      }
    }
    if (!cmap.containsKey(key)) {
      List<Integer> list = new ArrayList<>();
      list.add(0);
      cmap.put(key, list);
      return 0;
    }
    List<Integer> l = cmap.get(key);
    Collections.sort(l);
    int value = l.get(l.size() - 1) + 1;
    cmap.get(key).add(value);
    return value;
  }

  public boolean deallocate(String key, Integer number) {
    if (!cmap.containsKey(key)) {
      return false;
    }
    List<Integer> l = cmap.get(key);
    boolean o = l.remove(number);
    if (!o) {
      return false;
    }
    if (!umap.containsKey(key)) {
      List<Integer> list = new ArrayList<>();
      list.add(number);
      umap.put(key, list);
      return true;
    }
    umap.get(key).add(number);
    return true;
  }
}

最佳答案

更好的方法是存储下一个数字和每个键的释放列表:

public class Allocator {
    private final Map<String,Value> values = new HashMap<>();

    private class Value {
        private int nextValue = 0;
        private List<Integer> deallocatedValues = new ArrayList<>();

        public int allocate() {
            if (deallocatedValues.isEmpty()) {
                return nextValue++;
            else
                return deallocatedValues.remove();
        }

        public void deallocate(int value) {
            assert value >= 0 && value < nextValue;
            assert !deallocatedValues.contains(value);
            deallocatedValues.add(value);
        }
    }

    public int allocate(String key) {
        return values.computeIfAbsent(key, k -> new Value()).allocate();
    }

    public void deallocate(String key, int value) {
        assert values.containsKey(key);
        values.get(key).deallocate(value);
    }
}

关于java - 为特定键分配和取消分配数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57966594/

相关文章:

java - 基于浏览器的文档签名(带数字签名)的最佳跨浏览器解决方案是什么?

java - 随机排序(通过满足某些条件)

c - 如何访问 C 中 Struct 变量中的指针成员?

java - 为什么 HashSet 的内部实现创建一个 HashMap 来存储它的值?

java - 如何通过 Eclipse 在 java 中导入现有的 perl 项目?

java - 如何在java中对一个数组列表进行排序并以相同的顺序设置另一个列表

algorithm - 元素数组的多个查询更新

c# - 2d-bin-packing 将矩形放置在 x,y 位置的算法?

c - 当我们声明 struct node *p = NULL; 时,我们的意思是什么?

java - 解决 Java 9 模块系统中的可选依赖项