想法
- richer中存放的是金钱关系的值a,b,可以用一个hashmap存放,hashmap(b)中放比b更有钱的人
- 求answer,实际上是比较比x(包括x)更有钱的集合中,quiet最小的数的编号。
- 我们可以发现,例如,a比b有钱,c比a有钱。那么answer(b)=min{quiet(b),answer(a)}的一个比较关系,b的quiet和a的answer进行比较,所以想到递归/动态规划的方法。
- 转化为了每一个的最优子问题,来回调用的信息(从上往下调用)
- 时间复杂度O(n+m) 空间复杂度O(n+m),n为quiet的长度,m为richer的长度,遍历的时候会访问所有的节点,所以时空复杂度均为O(n+m)
class Solution {
public int[] loudAndRich(int[][] richer, int[] quiet) {
HashMap<Integer, ArrayList<Integer>> hm=new HashMap<>();
for(int i=0;i<richer.length;i++){
int a=richer[i][0],b=richer[i][1];
if(hm.containsKey(b)){
hm.get(b).add(a);
}else{
ArrayList<Integer> al=new ArrayList<>();
al.add(a);
hm.put(b,al);
}
}
int [] answer=new int[quiet.length];
for(int i=0;i<quiet.length;i++){
answer[i]=-1;
}
// 可以写成Arrays.fill(answer,-1);
for(int i=0;i<quiet.length;i++){
findAnswer(answer,quiet,hm,i);
}
return answer;
}
private int findAnswer(int [] answer,int [] quiet,HashMap<Integer,ArrayList<Integer>> hm,int pos){
if(answer[pos]!=-1) return answer[pos];
else{
if(!hm.containsKey(pos)){
answer[pos]=pos;
return answer[pos];
}else{
int len=hm.get(pos).size();
int value=pos;
for(int i=0;i<len;i++){
int val=findAnswer(answer,quiet,hm,hm.get(pos).get(i));
if(quiet[val]<quiet[value]){
value= val;
}
}
answer[pos]=value;
return answer[pos];
}
}
}
}
想法
本题可以用拓扑排序实现,利用richer构建图,访问比x小的点,每次x更新,就去遍历比它小的数