851. 喧闹和富有

题目

想法

  1. richer中存放的是金钱关系的值a,b,可以用一个hashmap存放,hashmap(b)中放比b更有钱的人
  2. 求answer,实际上是比较比x(包括x)更有钱的集合中,quiet最小的数的编号。
  3. 我们可以发现,例如,a比b有钱,c比a有钱。那么answer(b)=min{quiet(b),answer(a)}的一个比较关系,b的quiet和a的answer进行比较,所以想到递归/动态规划的方法。
  4. 转化为了每一个的最优子问题,来回调用的信息(从上往下调用)
  5. 时间复杂度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更新,就去遍历比它小的数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值