方法一、拓扑排序

78 阅读1分钟

题目:
算法:
方法一: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
}