喧闹和富有
难度:
标签:
题目描述
代码结果
运行时间: 38 ms, 内存: 22.7 MB
/*
* 题目思路:
* 同样,我们需要使用拓扑排序解决问题。但我们可以利用Java Stream来构建和处理数据。
* 1. 构建邻接表和入度数组。
* 2. 使用Java Stream初始化队列。
* 3. 使用Stream进行队列操作和更新安静值最小者。
*/
import java.util.*;
import java.util.stream.*;
public class Solution {
public int[] loudAndRich(int[][] richer, int[] quiet) {
int n = quiet.length;
List<List<Integer>> graph = IntStream.range(0, n)
.mapToObj(i -> new ArrayList<Integer>())
.collect(Collectors.toList());
int[] indegree = new int[n];
Arrays.stream(richer).forEach(pair -> {
graph.get(pair[0]).add(pair[1]);
indegree[pair[1]]++;
});
int[] answer = IntStream.range(0, n).toArray();
Queue<Integer> queue = IntStream.range(0, n)
.filter(i -> indegree[i] == 0)
.boxed()
.collect(Collectors.toCollection(LinkedList::new));
while (!queue.isEmpty()) {
int person = queue.poll();
graph.get(person).forEach(richerPerson -> {
if (quiet[answer[person]] < quiet[answer[richerPerson]]) {
answer[richerPerson] = answer[person];
}
if (--indegree[richerPerson] == 0) queue.offer(richerPerson);
});
}
return answer;
}
}
解释
方法:
这道题目可以使用深度优先搜索(DFS)来解决。首先,我们根据richer数组构建一个图g,其中g[y]包含所有比person y更有钱的人。然后,我们初始化一个答案数组ans,其中ans[x]表示在所有拥有的钱不少于person x的人中,最不安静的人的编号。我们对每个人i进行深度优先搜索,搜索过程中,如果我们访问到一个人x,我们首先检查ans[x]是否已经被计算过,如果没有,我们将ans[x]初始化为x自身,然后对于x的每一个财富大于他的人y,我们递归地调用dfs(y),并更新ans[x]为quiet值最小的人。最终,ans数组就是我们的答案。
时间复杂度:
O(r + n)
空间复杂度:
O(n)
代码细节讲解
🦆
如何确保构建的图g不会有环,从而使得DFS可以安全执行而不陷入无限循环?
▷🦆
在DFS过程中,如果存在多个人拥有相同的安静值,答案数组ans如何决定选取哪一个人作为最不安静的人?是否有特定的规则?
▷🦆
在构建图g时,是否有考虑到某些人可能没有比他们更有钱的人,即某些列表可能为空的情况?这种情况如何处理?
▷🦆
题解中没有明确说明如何处理已计算过的ans[x],在实际代码中是如何避免对同一节点重复计算的?
▷