问题描述
问题是:
客户希望查看到目前为止最畅销的商品。我们希望将这些数据有效地提供给我们的客户。
样品输入:
已售商品清单:
F | 400
B | 1000
A | 500
A | 600
C | 1000
D | 700
E | 300
样品输出
A | 1100
C | 1000
B | 1000
D | 700
我的想法是在第一个API processinput()
中,使用商品和价值的映射来跟踪到目前为止已售出的所有商品,然后将更新后的商品添加到最大优先级队列中。在第二个API processQuery()
中,只需从队列中选择前K个即可。 processQuery
中存在一个问题,时间复杂度为O(NlogN)
。
我们是否可以通过覆盖TreeMap
而用单个equalsTo
解决此问题, 'compareto
和hasCode
,以便该树图按值排序。因此,我们只是遍历TreeMap并返回topN个项目?
解决方法
假定输入是上述格式的字符串列表,第一步type Maybe<T> = T | null;
const sayHelloTo = (str: string) => console.log(`hello ${str}`);
function myFunc( x: string[] ) {
x.forEach(item => sayHelloTo(item))
}
const x = ['abc',null,'xyz'] as Maybe<string>[];
const newX = x.filter(item => item !== null);
// Error: newX still type Maybe<string>[] does not match the expected <string>[]
myFunc(newX);
是将输入列表转换为某些对象{name,num}的列表:
processInput
然后,第二种方法按名称分组,对总值求和,并返回类似的结果列表:
public static List<Obj> processInput(List<String> data) {
return Arrays.stream(data)
.map(s -> s.split("\\|"))
.map(arr -> new Obj(arr[0],Integer.parseInt(arr[1])))
.collect(Collectors.toList());
}
,
您需要在两个方向上进行有效访问:项目到达时,您需要根据其名称(A,B,C)获得汇总金额,但是要对它们进行排序,将使用汇总金额。我认为您可以使用Map
来按名称查找项目,并使用SortedSet
进行排序。由于金额本身不是唯一的(例如B和C在示例中均为1000),因此排序也应使用名称(因为它们是唯一的),这就是为什么一组足以满足该需求的原因:
import java.util.HashMap;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
public class Test {
static class Item implements Comparable<Item> {
final String name;
int amount;
Item(String name,int amount){
this.name=name;
this.amount=amount;
}
public int compareTo(Item o) {
if(o.amount<amount)
return -1;
if(o.amount>amount)
return 1;
return o.name.compareTo(name);
}
public String toString() {
return name+"|"+amount;
}
}
Map<String,Item> itemmap=new HashMap<>();
SortedSet<Item> sorted=new TreeSet<>();
void add(String name,int amount) {
Item i=itemmap.get(name);
if(i!=null) {
sorted.remove(i);
i.amount+=amount;
} else {
i=new Item(name,amount);
}
itemmap.put(name,i);
sorted.add(i);
}
public static void main(String[] args) {
Test t=new Test();
t.add("F",400);
t.add("B",1000);
t.add("xA",500);
t.add("xA",600);
t.add("C",1000);
t.add("D",700);
t.add("E",300);
System.out.println("itemmap: "+t.itemmap);
System.out.println("sorted: "+t.sorted);
}
}
它产生输出(在Ideone上测试:https://ideone.com/2d79aC)
itemmap: {B=B|1000,C=C|1000,D=D|700,E=E|300,F=F|400,xA=xA|1100} sorted: [xA|1100,C|1000,B|1000,D|700,F|400,E|300]
我故意将A
重命名为xA
,否则映射将为A|1100,C|1000
,但这只是字母顺序的巧合(散列了几个连续的单字母字符串实际上并没有混合订单)。 C和B的顺序相反,因为这就是您要的。如果您希望它们为B,然后为C,则交换compareTo()
,或仅返回当前的负号。