找出2个数组中是否存在共同元素

时间:2013-01-27 09:18:58

标签: java

给定两个整数数组,如何有效地找出两个数组是否有共同的元素?

有人可以提出比这更好的空间复杂性(我也很感激在程序中指出错误,谢谢!!)。

是否可以使用XOR解决此问题?

public boolean findcommon(int[] arr1, int[] arr2) {
  Set<int> s = new Hashset<int>();
  for(int i=0;i<arr1.length;i++) {
    if(!s.contains(arr1[i]))
      s.add(arr1[i]);
  }
  for(int i=0;i<arr2.length;i++) {
    if(s.contains(arr2[i]))
        return true;
  }
  return false;
}

4 个答案:

答案 0 :(得分:2)

因为您要求更节省空间的解决方案:

当您接受O(n log n)的运行时并允许更改数组时,您可以对它们进行排序,然后执行线性传递以查找公共元素。

答案 1 :(得分:1)

如果你只需要做ONCE,那么你不能比时间复杂度O(n + m)做得更好,其中n和m是各自的数组长度。你必须通过两个数组中的输入,没有选择(你怎么看待所有的输入?),所以只是输入处理将具有这种复杂性,没有必要做更有效的事情。如果你需要在数组增长时继续搜索,那就是另一种讨论。

因此,您建议的实施方式的问题归结为“包含”需要多长时间?由于你使用的是Hashset,contains是常量时间O(1),所以你得到O(n)来创建hashset和O(m)来验证第二个数组中的元素。 放在一起,O(n + m)。足够好;)

如果您正在寻找改进的空间复杂性,首先需要能够对原始阵列进行更改。但我认为没有任何方法可以使用比O(n)更少的额外空间,并且仍然可以在O(n + m)时间内执行。

注意:我不确定你在想什么XOR。如果您正在考虑按位或逻辑XOR,那么这里没有用处。如果您正在考虑设置XOR,那么它是否在逻辑上有用并不重要,因为它不在Java集的实现中,因此您仍然需要自己动手。

答案 2 :(得分:1)

鉴于您的解决方案仅尝试查找两个数组中是否存在元素,以下代码将为您执行此操作:

 public boolean findCommon(int[] arr1, int[] arr2) {
      HashTable hash = new HashTable();
      for (item : arr1){
         if !(hash.containsKey(item)){
            hash.put(item, "foo");
         }
      }
      for (item : arr2){
         if (hash.containsKey(item)){
           return(true);
         }
      }
      return(false);
 }

对于不共享单个元素的两个数组,这仍然具有O(n)的最坏情况复杂性。如果您最初的问题所暗示的是您所担心的是Space Complexity(例如,如果您不需要存储HashTable,您会很乐意接受性能损失),您可以按照以下方式进行操作:

    public boolean findCommon(int[] arr1, int[] arr2){
        for (item : arr1){
           for(item2 : arr2){
               if(item ==item2){
                   return(true);
               }
           }
        }
        return(false);
    }

这将解决你的空间复杂性问题,但会有(客观上可怕的)时间复杂度为O(n ^ 2)。

如果您要在其周围放置更多参数,可以简化这种情况(假设您碰巧知道至少有一个数组已排序,或者更好,两者都已排序)。

但是在通配符示例中,您问我相信它真的会归结为具有空间复杂度的HashTable的O(n),或者具有较小空间复杂度的O(n ^ 2)。

答案 3 :(得分:0)

你可以用O(n * m)的算法来改善占用空间(这是问题吗?)。只需取出每对元素并进行比较......这很糟糕,但不会使用任何额外的内存。否则,您可以对两个数组进行排序(如果允许修改它们)并在O(max(n,m))中找到公共元素。