寻找4个元素的共同元素

时间:2014-05-02 14:24:06

标签: java map set graph-theory

我有一张地图TreeMap<Integer, Set<Integer>> adjacencyLists和一个整数集TreeSet<Integer> specialNodes

地图代表图表的邻接列表。

我想从adjacencyLists中挑选密钥,并在specialNodes中找出它们之间是否存在共同的密钥。

有没有办法有效地做到这一点?

示例:

adjacencyLists如下:

[1, [2 3 4 5]]
[2, [1 5]]  
[3, [1 4 5]]  
[4, [1 3]]  
[5, [1 2 3]]

specalNodes如下:

[1 3 4 5]

在此示例中,4的第一个和第三个条目的值中包含5adjacencyLists

因此,编写一个函数findCommon(1,3)应该给我[4 5]
同样,findCommon(1,5)应返回null,因为&#39; 2&#39;是唯一的常见元素,不在specialNodes

4 个答案:

答案 0 :(得分:2)

这是一步一步的过程。

  1. 从键中获取两个值。 O(logn)
  2. 对它们进行排序。 O(nlogn)
  3. 找到common elementsO(m+n)
  4. specialNodes中搜索常见元素。 O(m+n)
  5. 因此,最坏情况时间复杂度= O(nlogn)

答案 1 :(得分:1)

所以,如果我正确理解你已经为每个整数列出了它的邻接,那么它就已经有了一套?

我能看到的最简单有效的方法是使用另一个Set。设置非常快,用于检查它们是否已包含值。

Set<Integer> adjacent = new HashSet<>();

for (Integer i: toCheck) {
   int oldCount = adjacent.size();
   Set<Integer> check = adjacencyLists.get(i);
   adjacent.addAll(check);
   if (adjacent.size() != oldCount+check.size()) {
      // Duplicate found
      return true;
   }
}
return false;

如果您需要知道公共的标识,那么通过执行单独的添加调用而不是执行addAll来循环,并检查每个添加是否成功。实际上这可能更有效,因为不需要进行大小检查:

Set<Integer> adjacent = new HashSet<>();

for (Integer i: toCheck) {
   Set<Integer> check = adjacencyLists.get(i);
   for (Integer c: check)
      if (!adjacent.add(c)) {
         // Duplicate found
         return c;
      }
}
return null;

刚看到普通会员完整名单的请求:

Set<Integer> adjacent = new HashSet<>();
Set<Integer> results = new HashSet<>();

for (Integer i: toCheck) {
   Set<Integer> check = adjacencyLists.get(i);
   for (Integer c: check)
      if (!adjacent.add(c)) {
         // Duplicate found
         results.add(c);
      }
}
return results;

答案 2 :(得分:1)

不是100%肯定你的意思,但这是我的想法。一种可能的方法是使用像BFS这样的搜索算法。由于所有这四个节点必须具有一个公共节点,因此意味着您将四个节点中的一个用作root用户并搜索三个节点中的每个节点。如果搜索所有三个成功,则它们必须具有一个公共节点。

答案 3 :(得分:0)

显而易见的解决方案是创建specialNodes的副本,然后在您正在考虑的所有集合上调用其方法retainAll,结果集合包含公共节点。你试过吗?它不够有效吗?

代码:

Set findCommons(int a, int b) {
    HashSet commonNodes = new HashSet(specialNodes);

    commonNodes.retainAll(adjacencyLists.get(a));
    commonNodes.retainAll(adjacencyLists.get(b));
    return commonNodes;
}