给定两个整数数组,如何有效地找出两个数组是否有共同的元素?
有人可以提出比这更好的空间复杂性(我也很感激在程序中指出错误,谢谢!!)。
是否可以使用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;
}
答案 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))中找到公共元素。