【发布时间】:2018-02-14 15:09:25
【问题描述】:
更新
给定客户为不同酒店提供的一组评论和一个包含“Good Words”的字符串,您需要根据评论的“Goodness Value”降序排序(较高的goodness value首先)。我们将字符串的“Goodness Value”定义为该字符串中“Good Words”的数量。
注意:排序应该是稳定的。如果评论 i 和评论 j 具有相同的“Goodness Value”,那么它们的原始顺序将被保留。
问题
使用priority queue 排列上述顺序并不稳定,因为轮询堆数组不会以相同的顺序返回相同的值。
同时,我查看了这个博客:https://lemire.me/blog/2017/03/13/stable-priority-queues/。
有没有更好的方法来稳定优先级队列排序?或任何其他更好的DS?我能想到的一种方法是将其放入arrays 和sorting 中。 Treemap 不能像 key 那样有用,因为涉及重复条目或类似计数的多个单词。
问题: https://www.interviewbit.com/problems/hotel-reviews/
这行得通
输入: S = "cool_ice_wifi" R = ["water_is_cool", "cold_ice_drink", "cool_wifi_speed"]
输出: ans = [2, 0, 1]
在这里,排序的评论是 ["cool_wifi_speed", "water_is_cool", "cold_ice_drink"]
这个测试用例不起作用。
A:“a_b_c”
B:[“a_b”,“b_c”,“a_c”]
public class Solution {
private static final int ALPHA_SIZE = 26;
public static class Reviews implements Comparable<Reviews> {
private int pos;
private int score;
@Override
public boolean equals(Object o) {
if(this == o) return true;
if(o == null || this.getClass()!=o.getClass()) return false;
Reviews r = (Reviews)o;
if(r.score!=this.score) return false;
return true;
}
@Override
public int compareTo(Reviews r) {
return this.score - r.score;
}
}
public static class TrieNode {
TrieNode[] letter;
boolean isTail;
public TrieNode() {
isTail = false;
letter = new TrieNode[ALPHA_SIZE];
for(int i = 0; i < ALPHA_SIZE; i++) {
letter[i] = null;
}
}
}
static TrieNode root;
public static void add(String word) {
TrieNode curr = root;
for(char ch : word.toCharArray()) {
if(curr.letter[ch-'a']==null) curr.letter[ch-'a'] = new TrieNode();
curr = curr.letter[ch-'a'];
}
curr.isTail = true;
}
public void addAll(String[] words) {
for(String word : words) {
this.add(word);
}
}
public static boolean contains(String word) {
TrieNode curr = root;
for(char ch : word.toCharArray()) {
if(curr.letter[ch-'a']!=null) {
curr = curr.letter[ch-'a'];
} else {
return false;
}
}
return curr.isTail;
}
public ArrayList<Integer> solve(String A, ArrayList<String> B) {
root = new TrieNode();
String[] words = A.split("_");
addAll(words);
ArrayList<Integer> res = new ArrayList<>();
Reviews cur;
Queue<Reviews> q = new PriorityQueue<>(Collections.reverseOrder());
for(int i = 0; i < B.size(); i++) {
cur = new Reviews();
cur.score = countGW(B.get(i));
cur.pos = i;
q.add(cur);
}
while(!q.isEmpty()) {
cur = q.poll();
res.add(cur.pos);
}
return res;
}
public int countGW(String x) {
String[] xs = x.split("_");
int res = 0;
for(String y : xs) {
if(contains(y)) {
res++;
}
}
return res;
}
}
【问题讨论】:
-
你的问题不清楚,包含很多不必要的代码。请创建一个minimal reproducible example:将3个项目放入PriorityQueue,取出,检查顺序是否正确,从那里取出。
-
当你覆盖 equals() 时,你总是需要 @Override hashCode(),这样两个相等的对象总是有相同的哈希值。也许这就是问题所在。否则,原来的问题对我来说有点模棱两可。不知道为什么“water_is_cool”出现在“cold_ice_drink”之前。
-
@GregT 这不是 100% 正确的。通过-约定-,您应该覆盖两者。但是,如果您无意在散列结构中使用您的对象,则也无需为此准备对象。并且要补充一点,优先队列不是哈希结构,因此 hashCode() 应该不是问题。 hashCode() 被覆盖以提高速度。它仍然可以在不覆盖它的情况下工作。
-
@Oskarzito 当然编译器不会抱怨,所以技术上你可以做到,但你可能会在不经意间引入很多错误。更多参考:stackoverflow.com/questions/2265503/…
-
@GregT 是的,这是一个非常好的和有趣的参考!但它只是指出散列函数的结果散列到不同的位置,如果没有覆盖,这是真的。但它仍然可以在没有的情况下工作,即使在不必要的情况下会发生(并被处理)等冲突。所以,如前所述,如果不需要将对象用作哈希结构中的键,它不会通过不覆盖而影响任何事情它。
标签: java sorting data-structures priority-queue trie