我有以下学生的信息,并有相应的分数和等级
Name Marks Rank
A 30 1
B 20 2
C 10 3学生的排名与学生的分数成反比。我必须找到最佳的数据结构来存储上述信息,以便以最优的方式(最佳时间复杂度)执行以下操作。可以假定学生的名字是独一无二的。
我正在考虑使用两个散列映射,一个用于学生和标记映射,另一个用于学生姓名和等级映射。有更好的数据结构吗?有什么办法能让我利用排名与分数成反比的事实吗?
发布于 2015-06-24 10:01:41
这可以通过两种数据结构来完成:
这允许您在O(logn)中执行以下所有操作
此外,在O(1) (平均案例)中,仅使用散列图就可以找到学生的成绩。
注意:
您可以将学生名->年级图的实现转换为树映射,而不是散列图,而不会对复杂性造成太大影响,并保证更好的最坏情况行为。(发现职系亦为O(logn),而非O(1)。)
发布于 2015-06-24 12:24:56
我的建议也是使用两个HashMap,但其中一个是逐步填充的,而不是增加排序复杂性来更新时间。这将提供以下属性:
byStudentreorder从addOrUpdate方法中提取出来,分批更新,并在每个批处理之后从外部调用重新排序。byRank。class MyClass {
Comparator<RankedStudent> comp = Comparator.comparingInt(e -> e.marks);
private Map<String, RankedStudent> repo = new HashMap<>();
private Map<Integer, RankedStudent> rankCache = new HashMap<>();
public RankedStudent getByStudent(String student) {
return repo.get(student);
}
public RankedStudent getByRank(Integer rank) {
return Optional.ofNullable(rankCache.get(rank)).orElseGet(() -> {
rankCache.putIfAbsent(rank, repo.values().stream().sorted((s1, s2) -> rank == s1.rank ? 1 : 0)
.findFirst().orElse(null));
return rankCache.get(rank);
});
}
public void addOrUpdate(String student, Integer marks) {
repo.put(student, new RankedStudent(student, marks, -1));
reorder();
}
public void reorder() {
final Iterator<RankedStudent> it = repo.values().stream().sorted(comp.reversed()).iterator();
IntStream.range(0, repo.size()).boxed().forEach(i -> it.next().rank = i + 1);
rankCache.clear();
}
}
class RankedStudent {
public String name;
public int marks;
public int rank;
public RankedStudent(String name, int marks, int rank) {
this.name = name;
this.marks = marks;
this.rank = rank;
}
}https://stackoverflow.com/questions/31023173
复制相似问题