我正在寻找一个数据结构来帮助我管理一个整数池。它是一个池,我将池中的整数移除一段时间,然后将它们放回去,期望它们将被再次使用。但它有一些其他奇怪的约束,所以常规池不能正常工作。
硬性要求:
如果它们有助于选择数据结构,请使用它们,否则忽略它们:
我有一个有效的解决方案,但感觉不够优雅 我的(次优)解决方案
恒定大小的游泳池 将所有可用的整数放入有序集(free_set)中 当请求新的整数时,从free_set中检索最小值 将所有正在使用的整数放入另一个有序集(used_set) 当请求最大值时,从used_set中检索最大值。
有一些优化可能有助于我的特定解决方案(优先级队列,memoization等)。但我的整个方法似乎很浪费。
我希望有一些完美适合我的问题的深奥数据结构。或者至少是一种更好的汇集算法。
答案 0 :(得分:0)
伪类:
class IntegerPool {
int size = 0;
Set<int> free_set = new Set<int>();
public int Acquire() {
if(!free_set.IsEmpty()) {
return free_set.RemoveSmallest();
} else {
return size++;
}
}
public void Release(int i) {
if(i == size - 1) {
size--;
} else {
free_set.Add(i);
}
}
public int GetLargestUsedInteger() {
return size;
}
}
修改强>
RemoveSmallest
并非全部有用。 RemoveWhatever
已经足够了。因此Set<int>
可以被LinkedList<int>
替换为更快的替代方案(甚至是Stack<int>
)。
答案 1 :(得分:0)
为什么不使用平衡的二叉搜索树?您可以将指针/迭代器存储到min元素并免费访问它,并在插入/删除后进行O(1)操作后更新它。如果使用自平衡树,则插入/删除为O(log(n))。详细说明:
插入:只需将新元素与之前的分钟进行比较;如果最好让迭代器指向新的最小值。
删除:如果min被删除,那么在删除之前找到后继(你可以通过向前走迭代器前进1步),然后把那个人当作新的min。< / p>
虽然理论上可以使用某种复杂的超级堆数据结构(即Fibonacci堆)做得稍好一些,但实际上我认为你不想处理类似的事情来节省一点点对数因子。此外,作为奖励,您可以免费快速进行有序遍历 - 更不用说现在大多数编程语言都可以快速实现开箱即用的自平衡二叉搜索树(如红黑树/ avl等) )。
^除了javascript:P
编辑:想到更好的答案。