[英]Reduce the time complexity of the code to find duplicates in an Array from N*N
最近,我在一次采访中被要求写代码以确定整数数组是否包含简单的重复项,因为我确信地告诉他,我将迭代这些元素,如果该数组不包含该元素,则将每个元素添加到一个新数组中如果已经返回,则返回true,否则返回false
该代码将是这样的
//complexity is N*N
public static boolean findIfArrayHasDuplicates(int[] array){
int[] newArr = new int[array.length];
List<Integer> intList = new ArrayList<Integer>();
for (int var: array){
if(intList.contains(var)){
return true;
}else{
intList.add(var);
}
}
return false;
}
}
他要求我计算我编写的代码的时间复杂度
我回答了
N用于循环的迭代N(N + 1)/ 2用于查找元素是否存在于新列表中N用于在列表中添加元素
O()表示法中的总N + N + N * N / 2 + N / 2乘以2并简化,因为N趋于无穷大,因此可以简化O(N ^ 2)
他继续问我是否有更好的方法,我回答是否可以将元素添加到集合中,如果集合的大小小于包含重复项的数组的大小,则比较大小,问它的复杂性是什么,猜猜它是什么仍然是O(N ^ 2),因为将代码添加到集合中的代码将必须首先查看其是否已经在集合中。 如何使用所需的内存减少O(N ^ 2)的复杂度。 任何想法如何做到这一点?
他继续问我是否有更好的方法,我回答是否可以将元素添加到集合中,如果集合的大小小于包含重复项的数组的大小,则比较大小,问它的复杂性是什么, 猜猜它是什么仍然是NN,因为向集合中添加元素的代码必须首先查看其是否已经在集合中
错了 如果要将元素添加到HashSet
,则需要花费O(1)
时间来添加每个元素(包括检查元素是否已经存在),因为您要做的就是计算hashCode
来定位可能包含元素(需要恒定的时间),然后搜索存储在该仓中的元素(假设每个仓中元素的平均数量受常数约束,这也需要预期的恒定时间)。
因此,总运行时间为O(N)
,没有任何改进(您找不到小于O(N)
重复项)。
我认为如果您查看HashSet
基本工作机制将很有用。 HashSet
在内部是数组,但是数据访问(例如“检查元素是否存在”或“添加/删除元素”)的时间复杂度为O(1),因为它采用了映射机制来映射对象。到存储它的索引。 例如,如果您有一个HashSet和一个整数,并且执行hashSet.contains(integer)
,则程序将首先获取该整数并计算其哈希码,然后使用映射机制(因实现而异)查找存储它的索引。 假设我们的哈希码为4,并使用最简单的映射机制映射到索引4,那么我们将检查基础数组的第4个元素是否为空。 如果是,则hashSet.contains(integer)
将返回true
,否则返回false
。
提供的代码的复杂度为O(N ^ 2)。 但是,下面给出的代码是复杂度O(N)。 它使用HashSet,它需要O(1)操作才能插入和搜索。
public static boolean findIfArrayHasDuplicates(int[] array){
HashSet<Integer> set = new HashSet<Integer>();
set.add(array[0]);
for (int index = 1; index < array.length; index++) {
if(!set.add(array[index]))
return true;
}
return false;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.