我有一个存储大量任务的系统。每个任务都有以下参数:
Time t
Priority p
每项任务都有一个独特的时间。这意味着没有2个任务可以具有相同的时间参数 但是,优先级并不是唯一的。多个任务可以具有相同的优先级。
我需要设计一个可以解决四种类型查询的系统。每种类型的查询的概率同样可能。以下是查询类型:
UpdateTask(T,P)
此查询希望系统将任务的优先级设置为t
到优先级p
。如果系统中不存在该任务,则会创建一个新任务。如果任务存在,则更新其优先级。
DeleteTask活动(t)的
此查询希望系统删除与时间t
关联的任务。如果系统中不存在此类任务,则无需采取任何措施。
GetMaximumPriority()和GetMinimumPriority()
此查询要求系统打印系统中可用任务的最低优先级和最高优先级。
GetPriorityofTaskAtMaximumTime()
此查询希望系统打印具有参数t
(时间)的最大值的任务的优先级
我需要为这个系统设计数据结构,并为这些数据结构实现算法。我需要在Java中实现它。
我的方法:创建一个HashMap
,其中Key为Time,Value为Priority。 HashMap
允许我在固定时间内解决前两个查询。但最后两个查询的时间复杂度为O(n)
。
问题:针对此问题,是否有更好的时间高效且节省空间的数据结构和算法?我主要需要一种方法来解决这个问题。完全实现的代码不是必需的。谢谢。
答案 0 :(得分:3)
一种可能的方法是维护两个索引:一个用于时间,一个用于优先级。让我们采用两个平衡的搜索树,并进行恒定的时间firstKey()
/ lastKey()
操作。我将使用TreeMap
的接口,但它应该具有类似于c ++的std::map
的实现(它只是在更新期间维护迭代器到第一个和最后一个元素)。
第一张地图为Map<Time, Priority> tasks
,第二张为Map<Priority, Integer> priorities
。每个现有优先级值的第二个映射存储具有此优先级值的任务数。因此,您可以将tasks
用于第四个查询,将priorities
用于第三个查询。
UpdateTask(t,p)
Priority oldp = tasks.put(t, p);
if (oldp != null) {
decreasePriority(oldp);
}
increasePriority(p);
复杂性: O(log(n))
<强> DeleteTask活动(t)的强>
if (tasks.containsKey(t)) {
Priority oldp = tasks.get(t);
tasks.remove(t);
decreasePriority(oldp);
}
复杂性: O(log(n))
GetMaximumPriority(),GetMinimumPriority()
return priorities.lastKey();
return priorities.firstKey();
复杂性: O(1)(正确lastKey()
/ firstKey()
实施,O(log(n))
java.util.TreeMap
。)
<强> GetPriorityofTaskAtMaximumTime()强>
return tasks.lastEntry().getValue();
复杂性: O(1)(正确lastEntry()
实施,O(log(n))
java.util.TreeMap
void increasePriority(p) {
if (priorities.hasKey(p)) {
priorities.put(p, priorities.get(p) + 1);
} else {
priorities.put(p, 1);
}
}
void decreasePriority(p) {
int count = priorities.get(p);
if (count > 1) {
priorities.put(p, count - 1);
} else {
priorities.remove(p);
}
}
因此,您将避免操作中的线性复杂性。
答案 1 :(得分:1)
一般approcah - 可能会根据您的数据类型进行更改,我认为您可以使用一种类型的地图数据类型作为关键时间和优先级。每当您想要删除数据时,使用时间作为键和删除来搜索该地图,同样您可以使用时间作为键进行更新。
然后,您可以根据时间和优先级分别列出一个列表,然后根据需要对列表进行排序。
答案 2 :(得分:0)
您可以尝试使用Heap或PriorityQueue,它可以按照here的规定在O(1)中找到最小值和最大值。
他们还删除并提取O(log n)中的min和max,但搜索将保持在O(n)。
您可能必须为Task类实现Comparator
...