Algorithm Graph

记录 Graph 的算法实现

“207. Course Schedule”

func canFinish(numCourses int, prerequisites [][]int) bool {
    in := make([]int, numCourses)
    g := make(map[int][]int)
    for _, pre := range prerequisites {
        g[pre[1]] = append(g[pre[1]], pre[0])
        in[pre[0]]++
    }

    q := make([]int, 0, numCourses)
    for i := 0; i < numCourses; i++ {
        if in[i] == 0 {
            q = append(q, i)
        }
    }

    zeroCount := 0
    for len(q) > 0 {
        cur := q[0]
        q = q[1:]
        zeroCount++
        for _, next := range g[cur] {
            in[next]--
            if in[next] == 0 {
                q = append(q, next)
            }
        }
        delete(g, cur)
    }

    return zeroCount == numCourses
}

“277. Find the Celebrity”

for (int i = 0, j = 0; i < n; i++) {
    for (j = 0; j < n; j++) {
        if (i != j && knows(i, j)) break; //if i knows j, i is not celebrity
        if (i != j && !knows(j, i)) break; //if j don't know i, not celebrity
    }
    if (j == n) return i; //i does not know any j , but all j know i
}
return -1;

“310. Minimum Height Trees”

vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
    if (n == 1) return {0};
    vector<unordered_set<int>> g(n);
    for (auto &e : edges) {
        g[e[0]].insert(e[1]);
        g[e[1]].insert(e[0]);
    }
    queue<int> q;
    for (int i = 0; i < n; ++i) {
        if (g[i].size() == 1)
            q.push(i);
    }
    while (n > 2) {
        int size = q.size();
        n -= size;
        for (int i = 0; i < size; ++i) {
            int e = q.front(); q.pop();
            for (auto a : g[e]) {
                g[a].erase(e);
                if (g[a].size() == 1)
                    q.push(a);
            }
        }
    }
    vector<int> res;
    while (q.size()) {
        res.push_back(q.front());
        q.pop();
    }
    return res;
}

“332. Reconstruct Itinerary”

unordered_map<string,multiset<string>> m_;	// tickets map
vector<string> res_;
void dfs(string start) {
    while (m_[start].size()) {
        string next = *m_[start].begin();
        // 注意,这里是multiset,所以erase(iterator)只会删除一个元素。
        m_[start].erase(m_[start].begin());
        dfs(next);
    }
    // 按照Hierholzer算法,应该插入到最左边,所以res最后要reverse一下。
    res_.push_back(start);
}
vector<string> findItinerary(vector<vector<string>>& tickets) {
    for (auto i : tickets) {
        m_[i[0]].insert(i[1]);
    }
    dfs("JFK");
    // 按照Hierholzer算法,应该插入到最左边,所以res最后要reverse一下。
    reverse(res_.begin(), res_.end());
    return res_;
}

“743. Network Delay Time”

// Dijkstra
func networkDelayTime(times [][]int, n int, k int) int {
    dist := make([]int, n)
    for i := range dist {
        dist[i] = math.MaxInt32
    }
    edges := make(map[int][][2]int)
    for _, t := range times {
        edges[t[0]] = append(edges[t[0]], [2]int{t[1], t[2]})
    }

    h := &myHeap{[2]int{k, 0}}
    for h.Len() > 0 {
        edge := heap.Pop(h).([2]int)
        if dist[edge[0]-1] == math.MaxInt32 {
            for _, w := range edges[edge[0]] {
                heap.Push(h, [2]int{w[0], edge[1]+w[1]})
            }
        }
        if dist[edge[0]-1] > edge[1] {
            dist[edge[0]-1] = edge[1]
        }
    }

    maxVal := 0
    for _, d := range dist {
        if d == math.MaxInt32 {
            return -1
        } else if d > maxVal {
            maxVal = d
        }
    }

    return maxVal
}

type myHeap [][2]int // [vertex,dist]
func (p myHeap) Len() int {
    return len(p)
}
func (p myHeap) Less(a, b int) bool {
    return p[a][1] < p[b][1]
}
func (p *myHeap) Swap(a, b int) {
    (*p)[a], (*p)[b] = (*p)[b], (*p)[a]
}
func (p *myHeap) Push(x interface{}) {
    *p = append(*p, x.([2]int))
}
func (p *myHeap) Pop() interface{} {
    n := len(*p)-1
    tmp := (*p)[n]
    (*p) = (*p)[:n]
    return tmp
}
// Bellmen-Ford
func networkDelayTime(times [][]int, n int, k int) int {
    dp := make([]int, n)
    for i := range dp {
        dp[i] = math.MaxInt32
    }
    dp[k-1] = 0
    for i := 1; i < n; i++ {
        cur := append(dp[:0:0], dp...)  // perfect copy
        for _, t := range times {
               cur[t[1]-1] = min(cur[t[1]-1], dp[t[0]-1]+t[2])
        }
        dp = cur
    }

    maxVal := 0
    for _, v := range dp {
        if v == math.MaxInt32 {
            return -1   // 有不可达结点
        } else if v < 0 {
            return -1   // 存在负权边环
        } else if v > maxVal {
            maxVal = v
        }
    }

    return maxVal
}
// Floyd-Warshall
func networkDelayTime(times [][]int, n int, k int) int {
    matrix := make([][]int, n)
    for i := 0; i < n; i++ {
        matrix[i] = make([]int, n)
        for j := range matrix[i] {
            matrix[i][j] = math.MaxInt32
        }
        matrix[i][i] = 0
    }
    for _, t := range times {
        matrix[t[0]-1][t[1]-1] = t[2]
    }

    for k := 0; k < n; k++ {
        for i := 0; i < n; i++ {
            for j := 0; j < n; j++ {
                if matrix[i][j] > matrix[i][k] + matrix[k][j] {
                    matrix[i][j] = matrix[i][k] + matrix[k][j]
                }
            }
        }
    }

    maxVal := 0
    for i := 0; i < n; i++ {
        if matrix[k-1][i] == math.MaxInt32 {
            return -1
        } else if matrix[k-1][i] > maxVal {
            maxVal = matrix[k-1][i]
        }
    }

    return maxVal
}

“787. Cheapest Flights Within K Stops”

// Bellmen-Ford
func findCheapestPrice(n int, flights [][]int, src int, dst int, k int) int {
    dp := make([]int, n)
    for i := range dp {
        dp[i] = math.MaxInt32
    }
    dp[src] = 0

    for i := 0; i <= k; i++ {
        cur := append(dp[:0:0], dp...)
        for _, f := range flights {
            cur[f[1]] = min(cur[f[1]], dp[f[0]]+f[2])
        }
        dp = cur
    }

    if dp[dst] == math.MaxInt32 {
        return -1
    }
    return dp[dst]
}

“1192. Critical Connections in a Network”

func criticalConnections(n int, connections [][]int) (ret [][]int) {
    seq := 0
    dfn, low, graph := make([]int, n), make([]int, n), make([][]int, n)
    for i := range dfn {
        dfn[i] = -1
    }
    for _, c := range connections {
        graph[c[0]] = append(graph[c[0]], c[1])
        graph[c[1]] = append(graph[c[1]], c[0])
    }

    var dfs func(int, int)
    dfs = func(cur, from int) {
        seq++
        dfn[cur], low[cur] = seq, seq
        fmt.Println("in", cur, seq, seq)
        for _, next := range graph[cur] {
            if next == from {
                continue    // 避免死循环
            }
            if dfn[next] == -1 {
                dfs(next, cur)
                if low[next] > dfn[cur] {
                    ret = append(ret, []int{cur, next})
                }
            }
            fmt.Println("low", cur, low[cur], low[next])
            low[cur] = min(low[cur], low[next])
        }
    }

    // 由于题目是联通图,所以只需要从任意一点出发
    dfs(0, 0)
    return ret
}