我看到一个面试问题如下:
数组中的一个数字是重复的。找到它
简单的解决方案如下:
for(int i=0;i<n;i++){
{
dup = false;
for(j=0;j<n;j++){
if(i!=j && a[i]= a[j]){
dup = true;
}
if(dup == true)
return a[i]
}
}
但我想在O(n log(n))和O(n)时间内实现它。我该怎么办?
答案 0 :(得分:6)
对数组进行排序(可以在第一个O(n Log n)中完成,然后只需要对相邻元素进行比较。或者只是将数组放入哈希表中并在找到第一个键时停止有一个exsting条目。
答案 1 :(得分:3)
我正在回答“在数组中查找重复元素?”
搜索i和j从0到&lt; n,然后你检查j!= i。相反,你可以像这样形成你的循环:
for (int i=0; i<n-1; i++)
{
for (j=i+1; j<n; j++)
{
if (a[i] == a[j])
{
return i;
}
}
}
return -1;
反复设置dup = false是无稽之谈。如果dup仍然是假的,或者它是真的,那么你将代码保留为'return'。
答案 2 :(得分:2)
在实际代码(Java)中编写先前的答案:
O(n log n)时间:
Arrays.sort(arr);
for (int i = 1; i < arr.length; i++)
if (arr[i] == arr[i - 1])
return arr[i];
throw new Exception(); // error: no duplicate
O(n)时间:
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i < arr.length; i++) {
if (set.contains(arr[i]))
return arr[i];
set.add(arr[i]);
}
throw new Exception(); // error: no duplicate
答案 3 :(得分:0)
参考java.util.TreeSet
实施红黑树底层,它是 O(n * log(n))。
答案 4 :(得分:0)
我建议使用 hash-map (假设没有冲突)来解决它。
private boolean hasDuplicate(int[] arr) {
Map<Integer, Boolean> map = new HashMap();
// find the duplicate element from an array using map
for (int i = 0; i < arr.length; i++) {
if(map.containsKey(arr[i])) {
return true;
} else {
map.put(arr[i], true);
}
}
return false;
}
时间复杂度:O(n)
空间复杂度:O(n)
另一种方法是排序和比较,但排序会增加额外开销。
答案 5 :(得分:0)
通过使用集合,我们可以使用下面的代码段 -
Set<String> set = new HashSet<String>();
for (String arrayElement : arr) {
if (!set.add(arrayElement)) {
System.out.println("Duplicate Element is : " + arrayElement);
}
}
答案 6 :(得分:0)
如下所示找到O(n)复杂性解决方案 -
int ar[]={0,1,2,3,0,2,3,1,0,2};
Set <Integer>mySet=new HashSet<>();
for(int n:ar){
if(!mySet.add(n)){
System.out.println(" "+n);
}
}
另一个空间复杂度较小的过程O(N)和可能的O(n Log n) -
public void duplicateElementSolution(int ar[]){
Arrays.sort(ar);
for(int i=0;i<(ar.length-1);i++){
if(ar[i]==ar[i+1]){
System.out.println(" "+ar[i]);
}
}
}
答案 7 :(得分:-1)
(当前形式的问题有点令人困惑 - 我的答案是假设问题是在数组中找到两个数字并求一个给定值)
由于给定的数组未排序,我假设不允许对数组进行排序(即不能更改数组的给定顺序)。
最简单的解决方案IMHO将迭代每个数字x
并检查数组中的任何位置是否出现I-x
。这基本上就是你的O(n ^ 2)解决方案正在做的事情。
通过使用某种快速设置数据结构使搜索更快,可以将其降低到O(n)或O(nlogn)。基本上,当我们迭代数组时,我们查询是否在集合中出现I-x
。
代码(在Python中):
l=[1,2,3,4,5,6,7,8,9]
seen=set()
I=11
for item in l:
if I-item in seen:
print "(%d,%d)"%(item,I-item)
seen.add(item)
解决方案的复杂性取决于您使用的set
数据结构的插入/查找复杂性。基于散列表的实现具有O(1)复杂度,因此它为您提供O(n)算法,而基于树的set
导致O(nlogn)算法。
编辑:
Python的set
的等效数据结构在C ++中为stl::set
,在Java中为TreeSet
/ HashSet
。行I-x in seen
将在Java中转换为seen.contains(I-x)
,在C ++中转换为seen.find(I-x)==seen.end()
。