上周我出席了一次采访。我得到了以下问题:
给定一个2n个元素的数组,并且这n个元素是相同的,其余的都是不同的。找到重复n次的元素。
对元素的范围没有限制。
有人可以给我一个有效的算法来解决这个问题吗?
答案 0 :(得分:7)
“给出了2n个元素的数组,这n个元素中的元素是相同的,剩下的都是不同的。找到重复n次的元素。”
这可以使用以下算法在O(n)中完成:
1)迭代数组,检查是否有任何元素[i]和[i + 1]相同。
2)迭代数组,检查是否有任何元素[i]和[i + 2]相同。
3)如果n = 2(因此长度= 4),检查0和3是否相同。
说明:
调用匹配元素m和非匹配元素r。
对于n = 2,我们可以构造mmrr,mrmr和mrrm - 所以我们必须检查间隙大小0,1和唯一可以有间隙大小2的地方。
对于n> 2,我们不能构造没有大小为0或1的间隙的数组。例如对于n = 3,你必须这样开始:mrrmr ...但是你必须放置一个m。类似地,对于n = 4,mrrmrrmm-没有大小为0或1的间隙将要求ms越多越多,随着n的增加越多。证明这很容易。
答案 1 :(得分:3)
你只需要找到两个相同的元素。
一个想法是:
从2n个元素中获取一个元素
如果它不在Set中,请将其放入。
重复,直到找到该集合中的一个。
答案 2 :(得分:1)
如果复杂性无关紧要,一种天真的方法就是使用两个循环,这是最坏情况下的O(n ^ 2)。
for(int i = 0; i < array.size(); i++){
for(int j = i + 1; j < array.size(); j++){
if(array[i] == array[j]){
// element found
}
}
答案 3 :(得分:1)
如果前四个元素都是不同的,那么数组必须包含一对连续的目标元素......
int find(int A[n])
{
// check first four elements (10 iterations = O(1))
for (int i = 0; i < 4; i++)
for (int j = i+1; j < 4; j++)
if (A[i] == A[j])
return A[i];
// find the consecutive pair (n-4 iterations = O(n))
for (int i = 3; i < n-1; i++)
if (A[i] == A[i+1])
return A[i];
// unreachable if input matches preconditions
throw invald_input;
}
这是单次通过和O(1)空间的最佳O(n)时间。
答案 4 :(得分:0)
如果你找到一个元素两次,那就是问题所说的元素:给出了2n个元素的数组,并且这n个元素中的元素是相同的,剩下的都是不同的。找到重复n次的元素。
答案 5 :(得分:0)
你有2n元素的数组,一半是相同的,剩下不同所以,请考虑以下情况,
ARRAY[2n] = {N,10,N,878,85778,N......};
或
Array[2n] = {10,N,10,N,44,N......};
现在简单的情况就像for循环一样,
if(ARRAY[i] == ARRAY[i+1])
{
//Your similar element :)
}
答案 6 :(得分:0)
我认为问题应该是“找到至少出现n + 1次的元素”,如果它只出现n次则可以是两次。
假设输入中有这样的元素,可以使用以下算法。
input array of 2*n elements;
int candidate = input[0];
int count = 1;
for (int i = 1; i < 2*n; ++i) {
if (input[i] == candidate) {
count++;
} else {
count --;
if (count == 0) candidate = input[i];
}
}
return candidate;
如果请求要查找是否存在元素n + 1次需要另一次遍历来查找上一步中找到的元素是否出现n + 1次。
修改强>
有人建议具有相同值的n个元素是连续的。 如果是这种情况,只需使用上述算法,并在计数达到n时停止。