题目:
算法:
方法一:dfs
func loudAndRich(richer [][]int, quiet []int) []int {
g := make([][]int, len(quiet))
ans := make([]int, len(quiet))
for i := range g {
ans[i] = -1
g[i] = append(g[i], i)
}
for i := range richer {
g[richer[i][1]] = append(g[richer[i][1]], richer[i][0])
}
var dfs func(person int)
dfs = func(person int) {
// 防止重复访问
if ans[person] != -1 {
return
}
ans[person] = person
for _, richerPerson := range g[person] {
dfs(richerPerson)
// 比person更有钱,更安静的人,一定是在ans[person] = min(ans[richerPerson1],ans[richerPerson2],...,ans[richerPersoni])
if quiet[ans[richerPerson]] < quiet[ans[person]] {
ans[person] = ans[richerPerson]
}
}
}
for i := range g {
dfs(i)
}
return ans
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
方法二:拓补排序
按没钱->有钱构建邻接表,将入度为0 的person加入队列 ,然后将他们的下游节点加入队列。直到队列为0。
对于队列中的元素,如果它比他们更穷的人比较,更安静,则将这个安静值赋给穷人。穷人入度减一,穷人入度为0,则入队列。
func loudAndRich(richer [][]int, quiet []int) []int {
g := make([][]int, len(quiet))
ans := make([]int, len(quiet))
inDegree := make([]int, len(quiet))
for i := range g {
// g[i] = append(g[i], i)
ans[i] = i
}
// g中有钱人指向没钱人
for i := range richer {
g[richer[i][0]] = append(g[richer[i][0]], richer[i][1])
inDegree[richer[i][1]] ++
}
queue := make([]int, 0)
// 拓补排序,将入度为0的人加入队列
for i := range inDegree {
if inDegree[i] == 0 {
queue = append(queue, i)
}
}
for len(queue) != 0 {
richerPerson := queue[0]
queue = queue[1:]
for _, person := range g[richerPerson] {
if quiet[ans[richerPerson]] < quiet[ans[person]] {
ans[person] = ans[richerPerson]
}
inDegree[person] --
if inDegree[person] == 0 {
queue = append(queue, person)
}
}
}
return ans
}
func min(a, b int) int {
if a < b {
return a
}
return b
}