2021-12-15每日一题练习
有一组 n
个人作为实验对象,从 0
到 n - 1
编号,其中每个人都有不同数目的钱,以及不同程度的安静值(quietness)。为了方便起见,我们将编号为 x
的人简称为 "person x
"。
给你一个数组 richer
,其中 richer[i] = [ai, bi]
表示 person ai
比 person bi
更有钱。另给你一个整数数组 quiet
,其中 quiet[i]
是 person i
的安静值。richer
中所给出的数据 逻辑自恰(也就是说,在 person x
比 person y
更有钱的同时,不会出现 person y
比 person x
更有钱的情况 )。
现在,返回一个整数数组 answer
作为答案,其中 answer[x] = y
的前提是,在所有拥有的钱肯定不少于 person x
的人中,person y
是最安静的人(也就是安静值 quiet[y]
最小的人)。
示例 1:
输入:richer = [[1,0],[2,1],[3,1],[3,7],[4,3],[5,3],[6,3]], quiet = [3,2,5,4,6,1,7,0] 输出:[5,5,2,5,4,5,6,7] 解释: answer[0] = 5, person 5 比 person 3 有更多的钱,person 3 比 person 1 有更多的钱,person 1 比 person 0 有更多的钱。 唯一较为安静(有较低的安静值 quiet[x])的人是 person 7, 但是目前还不清楚他是否比 person 0 更有钱。 answer[7] = 7, 在所有拥有的钱肯定不少于 person 7 的人中(这可能包括 person 3,4,5,6 以及 7), 最安静(有较低安静值 quiet[x])的人是 person 7。 其他的答案也可以用类似的推理来解释。
示例 2:
输入:richer = [], quiet = [0] 输出:[0]
提示:
n == quiet.length
1 <= n <= 500
0 <= quiet[i] < n
quiet
的所有值 互不相同0 <= richer.length <= n * (n - 1) / 2
0 <= ai, bi < n
ai != bi
richer
中的所有数对 互不相同- 对
richer
的观察在逻辑上是一致的
1 import java.util.ArrayList; 2 import java.util.Arrays; 3 import java.util.HashMap; 4 5 public class LoudAndRich { 6 int[] ans; 7 public int[] loudAndRich(int[][] richer, int[] quiet) { 8 HashMap<Integer, ArrayList<Integer>> map = new HashMap<>(); 9 for (int[] t:richer) { 10 if (map.containsKey(t[1])) map.get(t[1]).add(t[0]); 11 else { 12 ArrayList<Integer> list = new ArrayList<>(); 13 list.add(t[0]); 14 map.put(t[1],list); 15 } 16 } 17 // 将大小关系用hashmap记录下来 18 //key是personx,value是比personx有钱人的列表 19 ans=new int[quiet.length]; 20 //填充为-1,与可能的0区分开 21 Arrays.fill(ans,-1); 22 for (int i = 0; i < ans.length; i++) { 23 //如果没有人比personx有钱,则最小值为他本身 24 if (!map.containsKey(i)){ 25 ans[i]=quiet[i]; 26 }else{ 27 //否则是所有比他大的最小值 28 ans[i]=dfs(i,quiet,map); 29 } 30 } 31 //确定所有人的最小安静值后,利用hashmap寻找索引 32 //key为安静值,value为索引 33 HashMap<Integer, Integer> map1 = new HashMap<>(); 34 for (int i = 0; i < quiet.length; i++) { 35 map1.put(quiet[i],i); 36 } 37 for (int i = 0; i < ans.length; i++) { 38 ans[i]=map1.get(ans[i]); 39 } 40 return ans; 41 } 42 43 public int dfs(int i,int[] q,HashMap<Integer, ArrayList<Integer>> map){ 44 //如果没有比他有钱的列表,则返回本身 45 if (!map.containsKey(i)) return q[i]; 46 // 本身也计算在内,初始化为自己 47 int MAX=q[i]; 48 for (int j = 0; j < map.get(i).size(); j++) { 49 // 遍历比personx大的列表,取最小值 50 MAX=Math.min(q[map.get(i).get(j)],MAX); 51 //同时还要比较比当前值大的所有人的安静值,dfs实现 52 //优化:如果这个人的最小安静值已知,即ans值不为-1,则可以直接判断,否则才需要dfs深度遍历所有可能值 53 //可以节省很多时间 54 if (ans[map.get(i).get(j)]!=-1) MAX=Math.min(ans[map.get(i).get(j)],MAX); 55 else MAX=Math.min(dfs(map.get(i).get(j),q,map),MAX); 56 } 57 return MAX; 58 } 59 60 public static void main(String[] args) { 61 int[][] r={{1,0},{2,1},{3,1},{3,7},{4,3},{5,3},{6,3}}; 62 int[] q={3,2,5,4,6,1,7,0}; 63 System.out.println(Arrays.toString(new LoudAndRich().loudAndRich(r, q))); 64 } 65 }
自己写的笨方法,回头研究题解