代码随想录(一刷完结!!!)Day43-图论:力扣第1971e、684m题

1971e. 寻找图中是否存在路径

题目链接
代码随想录文章讲解链接

方法一:并查集

用时:10m6s

思路
  • 时间复杂度: O ( n log ⁡ n ) O(n\log{n}) O(nlogn)
  • 空间复杂度: O ( n ) O(n) O(n)
C++代码
class Solution {
private:
    vector<int> father;

    void init(int n) {
        // 初始化并查集,每个节点的根都是自己
        father = vector<int>(n);
        for (int i = 0; i < n; ++i) father[i] = i;
    }

    int find(int a) {
        // 查找根,并且压缩路径
        return a == father[a] ? a : father[a] = find(father[a]);
    }

    bool isSame(int a, int b) {
        // 判断两个节点是否在同一个集合中,即两个节点是否是同一个根
        return find(a) == find(b);
    }

    void join(int a, int b) {
        // 将a节点和b节点合并到同一个集合中,即让b的根指向a的根
        a = find(a);
        b = find(b);
        if (a != b) father[b] = a;
    }

public:
    bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
        init(n);  // 初始化并查集
        for (int i = 0; i < edges.size(); ++i) join(edges[i][0], edges[i][1]);  // 根据边更新并查集
        return isSame(source, destination);  // 判断两个节点是否在同一个集合
    }
};

方法二:BFS

用时:11m20s

思路
  • 时间复杂度: O ( n + m ) O(n+m) O(n+m)
  • 空间复杂度: O ( n + m ) O(n+m) O(n+m)
C++代码
class Solution {
public:
    bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
        // 构建邻接矩阵
        vector<vector<int>> adj(n);
        vector<bool> visited(n, false);
        for (int i = 0; i < edges.size(); ++i) {
            int node1 = edges[i][0];
            int node2 = edges[i][1];
            adj[node1].emplace_back(node2);
            adj[node2].emplace_back(node1);
        }
        // BFS
        queue<int> que;
        que.push(source);
        visited[source] = true;
        while (!que.empty()) {
            int cur = que.front();
            if (cur == destination) return true;
            que.pop();
            for (int i = 0; i < adj[cur].size(); ++i) {
                if (!visited[adj[cur][i]]) {
                    visited[adj[cur][i]] = true;
                    que.push(adj[cur][i]);
                }
            }
        }
        return false;
    }
};

方法三:DFS

用时:27m50s

思路

先构建邻接表,记录每个节点可以通往的节点;然后从source节点开始DFS,dfs递归函数的返回值不是void,是bool,当dfs过程中到达了destination,则返回true,注意不能直接递归内部不能直接返回dfs(…),因为即使一条dfs路径无法到达destination,也可能有其他路径。

  • 时间复杂度: O ( n + m ) O(n+m) O(n+m)
  • 空间复杂度: O ( n + m ) O(n+m) O(n+m)
C++代码
class Solution {
private:
    bool dfs(vector<vector<int>>& adj, vector<bool>& visited, int source, int destination) {
        if (source == destination) return true;
        visited[source] = true;
        for (int i = 0; i < adj[source].size(); ++i) {
            if (!visited[adj[source][i]] && dfs(adj, visited, adj[source][i], destination)) return true;
        }
        return false;
    }

public:
    bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
        vector<vector<int>> adj(n);
        vector<bool> visited(n, false);
        for (int i = 0; i < edges.size(); ++i) {
            int node1 = edges[i][0];
            int node2 = edges[i][1];
            adj[node1].emplace_back(node2);
            adj[node2].emplace_back(node1);
        }
        return dfs(adj, visited, source, destination);
    }
};

看完讲解的思考

无。

代码实现遇到的问题

无。


684m. 冗余连接

题目链接
代码随想录文章讲解链接

方法一:并查集

用时:25m21s

思路
  • 时间复杂度: O ( n log ⁡ n ) O(n\log{n}) O(nlogn)
  • 空间复杂度: O ( n ) O(n) O(n)
C++代码
class Solution {
private:
    vector<int> father;

    void init(int n) {
        father = vector<int>(n + 1);
        for (int i = 1; i < n + 1; ++i) father[i] = i;
    }

    int find(int a) {
        return a == father[a] ? a : father[a] = find(father[a]);
    }

    bool isSame(int a, int b) {
        return find(a) == find(b);
    }

    void join(int a, int b) {
        a = find(a);
        b = find(b);
        if (a != b) father[b] = a;
    }

public:
    vector<int> findRedundantConnection(vector<vector<int>>& edges) {
        init(edges.size());
        for (auto& edge : edges) {
            if (isSame(edge[0], edge[1])) return edge;
            join(edge[0], edge[1]);
        }
        return {0, 0};
    }
};

看完讲解的思考

无。

代码实现遇到的问题

无。


最后的碎碎念

一刷代码随想录完结撒花~!!!
虽然其实最后图论部分偷懒了,hard题都没做,主要是因为最近要开始找实习了,时间比较赶,hard题就先不做了,我找个日常实习而已,应该不会出图论的hard题目…吧…
所以图论只是把基础内容过了一下,接下来还是先赶紧去捡起前面的题型,复习一下。

你可能感兴趣的:(代码随想录,图论,leetcode,算法,c++)