我们有一个名为ratings
的链表,其中包含3个整数
userId,ItemId和实际评级的值(例如0到10)
此方法实际上返回程序从文件读取的用户i和项目j 的评级,如果没有评级则返回-1
BigOh(n)的方法:
public int getRating(int i, int j){
ratings.findFirst();
while(!ratings.empty()){
if(ratings.retrieve().getUserId() == i && ratings.retrieve().getItemId() == j)
return ratings.retrieve().getValue();
else
ratings.findNext();
}
return -1;
}
如何在BigOh(logn)中执行此操作?
或者,无论如何我可以使用二进制搜索树来解决它?
答案 0 :(得分:0)
您可以使用散列来完成 O(1)中的任务。请阅读此article以深入了解哈希。
由于您使用的是Java,因此可以使用HashMap来完成任务。请注意,hashing
技术的最差情况时间复杂度为 O(log n),但平均而言 O(1)。如果您对哈希表和摊销分析更感兴趣,请仔细阅读article。
代码示例:您可以使用所需属性创建Class
,并按如下方式实施equals
和hashCode
方法。 [阅读Java collections - hashCode() and equals()]
class Rating {
public int user_id; // id of the user who rated
public int item_id; // id of the item being rated
public Rating(int user_id, int item_id) {
this.user_id = user_id;
this.item_id = item_id;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof Rating)) {
return false;
}
Rating ratingObj = (Rating) o;
return ratingObj.user_id == user_id
&& ratingObj.item_id == item_id;
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + user_id;
result = 31 * result + item_id;
return result;
}
}
然后将值存储在HashMap
中,如下所示:
public static void main(String[] args) {
HashMap<Rating, Integer> ratingMap = new HashMap<>();
Rating rt = new Rating(1, 5); // user id = 1, item id = 5
ratingMap.put(rt, 3);
rt = new Rating(1, 2); // user id = 1, item id = 2
ratingMap.put(rt, 4);
rt = new Rating(1, 3); // user id = 1, item id = 3
ratingMap.put(rt, 5);
// now search in HashMap
System.out.println(ratingMap.get(new Rating(1, 3))); // prints 5
}
答案 1 :(得分:0)
如上所述,这很难在O(log n)中完成。您正在查看元素,直到找到所需的元素。在最坏的情况下,在循环结束之前,您将找不到所需的元素,从而使其成为O(n)。
当然,如果ratings
是一个字典,你将检索几乎为O(1)的值:用户ID作为键,例如作为值的评级列表。插入会有点慢但不多。
答案 2 :(得分:0)
简短的回答是:使用不同的数据结构。链接列表不能在任何其他中进行搜索,而不能在线性时间内进行搜索,因为每个元素都链接在一起而没有任何真实的相似性或顺序(如果列表已经排序,甚至 ,你仍然需要一些类型的定时遍历。)
您可以使用的一个数据结构是来自Guava的Table
。使用此数据结构,您必须做更多工作才能添加元素...
Table<Integer, Integer, Rating> ratings = HashBasedTable.create();
ratings.put(rating.getUserId(), rating.getItemId(), rating);
...但您可以快速检索非常 - 大约在HashBasedTable
支持LinkedHashSet<Integer, LinkedHashSet<Integer, Rating>>
后的大约O(1)时间。
ratings.get(i, j);