📌  相关文章
📜  图中所有与恰好 k 条边相连的顶点对(1)

📅  最后修改于: 2023-12-03 15:23:04.825000             🧑  作者: Mango

关于寻找与恰好 k 条边相连的顶点对

问题描述

给定一个无向图和一个正整数 k,求图中恰好有 k 条边相连的所有顶点对。

解决思路
解法一:暴力枚举

最简单直接的思路是暴力枚举每一对顶点,统计它们之间的边数,当边数等于 k 时记录下来。然而这种方法会超时,时间复杂度为 O(n^2)。

解法二:邻接表

为了优化时间复杂度,可以采用邻接表的数据结构。对于每一个顶点,记录下它所连接的所有顶点,这样可以在 O(边数) 的时间内遍历与每个顶点相连的顶点。我们可以使用一个哈希表 (unordered_map) 来记录每个顶点的邻居顶点,用一个变量 (int) 来记录每个顶点和其邻居顶点之间的边数。

具体地,在遍历的过程中,我们需要考虑以下几种情况:

  • 找到了一个度数恰好为 k 的顶点,记录下来。
  • 找到了一个度数大于 k 的顶点,继续遍历它的邻居顶点。
  • 找到了一个度数小于 k 的顶点,说明不能从当前顶点出发找到恰好 k 条边相连的顶点,因此直接跳过。

时间复杂度为 O(顶点数 + 边数)。

代码示例
vector<pair<int,int>> getVerticesWithKEdges(vector<vector<int>>& graph, int k) {
    vector<pair<int,int>> ans;
    int n = graph.size();
    unordered_map<int, unordered_map<int, int>> table;
    for (int i = 0; i < n; ++i) {
        for (int& v : graph[i]) {
            if (i < v) {
                table[i][v] = 0;
            }
        }
    }
    for (int i = 0; i < n; ++i) {
        for (auto& p : table[i]) {
            int v = p.first;
            int count = 0;
            for (int u : graph[i]) {
                if (u == v) continue;
                if (table[u].count(v)) {
                    ++count;
                }
            }
            p.second = count;
            if (count == k) ans.emplace_back(i, v);
        }
    }
    return ans;
}

以上代码使用了邻接表的方式来存储图,维护了一个哈希表 table 来记录每一对相连的顶点之间的边数。在遍历每个顶点的邻居顶点时,该算法使用了双重循环的方式来计算边数。在实现时将邻接表作为输入参数传递给该函数,其中 graph[i] 表示顶点 i 所连接的所有顶点。

总结

在本篇文章中,我们学习了如何使用邻接表和哈希表来解决寻找恰好 k 条边相连的所有顶点对的问题。使用该算法的时间复杂度为 O(顶点数 + 边数),空间复杂度为 O(边数)。