深度优先搜索
图
拓扑排序
数组
题目描述
有一组 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
的观察在逻辑上是一致的
解法
方法一:DFS
我们先用邻接表 $g$ 存储 $richer$ 数组中的信息,其中 $g[i]$ 表示所有比 $i$ 更有钱的人的集合。
然后对于每个人 $i$,我们用 DFS 遍历所有比 $i$ 更有钱的人,找到其中安静值最小的人,即为答案。
时间复杂度 $O(m + n)$,空间复杂度 $O(m + n)$。其中 $m$ 和 $n$ 分别为 $richer$ 数组和 $quiet$ 数组的长度。
Python3 Java C++ Go TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 class Solution :
def loudAndRich ( self , richer : List [ List [ int ]], quiet : List [ int ]) -> List [ int ]:
def dfs ( i : int ):
if ans [ i ] != - 1 :
return
ans [ i ] = i
for j in g [ i ]:
dfs ( j )
if quiet [ ans [ j ]] < quiet [ ans [ i ]]:
ans [ i ] = ans [ j ]
g = defaultdict ( list )
for a , b in richer :
g [ b ] . append ( a )
n = len ( quiet )
ans = [ - 1 ] * n
for i in range ( n ):
dfs ( i )
return ans
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 class Solution {
private List < Integer >[] g ;
private int n ;
private int [] quiet ;
private int [] ans ;
public int [] loudAndRich ( int [][] richer , int [] quiet ) {
n = quiet . length ;
this . quiet = quiet ;
g = new List [ n ] ;
ans = new int [ n ] ;
Arrays . fill ( ans , - 1 );
Arrays . setAll ( g , k -> new ArrayList <> ());
for ( var r : richer ) {
g [ r [ 1 ]] . add ( r [ 0 ] );
}
for ( int i = 0 ; i < n ; ++ i ) {
dfs ( i );
}
return ans ;
}
private void dfs ( int i ) {
if ( ans [ i ] != - 1 ) {
return ;
}
ans [ i ] = i ;
for ( int j : g [ i ] ) {
dfs ( j );
if ( quiet [ ans [ j ]] < quiet [ ans [ i ]] ) {
ans [ i ] = ans [ j ] ;
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 class Solution {
public :
vector < int > loudAndRich ( vector < vector < int >>& richer , vector < int >& quiet ) {
int n = quiet . size ();
vector < vector < int >> g ( n );
for ( auto & r : richer ) {
g [ r [ 1 ]]. push_back ( r [ 0 ]);
}
vector < int > ans ( n , -1 );
function < void ( int ) > dfs = [ & ]( int i ) {
if ( ans [ i ] != -1 ) {
return ;
}
ans [ i ] = i ;
for ( int j : g [ i ]) {
dfs ( j );
if ( quiet [ ans [ j ]] < quiet [ ans [ i ]]) {
ans [ i ] = ans [ j ];
}
}
};
for ( int i = 0 ; i < n ; ++ i ) {
dfs ( i );
}
return ans ;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 func loudAndRich ( richer [][] int , quiet [] int ) [] int {
n := len ( quiet )
g := make ([][] int , n )
ans := make ([] int , n )
for i := range g {
ans [ i ] = - 1
}
for _ , r := range richer {
a , b := r [ 0 ], r [ 1 ]
g [ b ] = append ( g [ b ], a )
}
var dfs func ( int )
dfs = func ( i int ) {
if ans [ i ] != - 1 {
return
}
ans [ i ] = i
for _ , j := range g [ i ] {
dfs ( j )
if quiet [ ans [ j ]] < quiet [ ans [ i ]] {
ans [ i ] = ans [ j ]
}
}
}
for i := range ans {
dfs ( i )
}
return ans
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 function loudAndRich ( richer : number [][], quiet : number []) : number [] {
const n = quiet . length ;
const g : number [][] = new Array ( n ). fill ( 0 ). map (() => []);
for ( const [ a , b ] of richer ) {
g [ b ]. push ( a );
}
const ans : number [] = new Array ( n ). fill ( - 1 );
const dfs = ( i : number ) => {
if ( ans [ i ] != - 1 ) {
return ans ;
}
ans [ i ] = i ;
for ( const j of g [ i ]) {
dfs ( j );
if ( quiet [ ans [ j ]] < quiet [ ans [ i ]]) {
ans [ i ] = ans [ j ];
}
}
};
for ( let i = 0 ; i < n ; ++ i ) {
dfs ( i );
}
return ans ;
}
GitHub