有一个n个数字的数组。一个数字重复n / 2次,其他n / 2个数字不同。找到重复的数字。 (最佳soln是o(n)正好n / 2 + 1比较。)
这里的主要问题是n / 2 + 1比较。 我有两个O(n)的解决方案,但他们正在进行超过n / 2 + 1的比较。
1>将数组的数量除以三个组。比较任何相同元素的n / 3组。 例如,数组是(1×10 3)(4 8 1)(11)....因此所需的比较数是7,其是> n / 2 + 1 即8/2 + 1 = 5
2 - ;将a [i]与[i + 1]和[i + 2]进行比较 例如,阵列是8 10 3 4 1 1 1 1
总共9次比较
我甚至感激一点帮助。 谢谢
空间复杂度为O(1)。
答案 0 :(得分:10)
当然如果所有其他都不同,你只需要比较所有对。如果您找到一对两个相等的数字,则您有这个数字
假设你有这样的数字(它只是关于索引)
[1,2,3,4,5,6,7,8,9,10]
然后你进行n / 2 + 1比较,就像这样
(1,2),(3,4),(5,6),(7,8),(9,7),(9,8)
如果所有对都不同,则返回10。
当你比较最后4个剩余数字(7,8,9,10)时,你知道其中至少有两个相同的数字并且你有3个比较。
答案 1 :(得分:1)
您只需要找到数组中存在两次的数字。
你刚刚从头开始,保留哈希或者你已经看过的数字,当你得到一个出现两次的数字时就停止了。
最糟糕的猫情景:你首先看到所有n / 2个不同的数字,然后下一个数字是重复.... n / 2 + 2 (因为你正在寻找的数字for不是n / 2唯一数字的一部分)
答案 2 :(得分:1)
关于O(1)空间复杂度的部分读得太晚,但无论如何,这是我的解决方案:
#include <iterator>
#include <unordered_set>
template <typename ForwardIterator>
ForwardIterator find_repeated_element(ForwardIterator begin, ForwardIterator end)
{
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
std::unordered_set<value_type> visited_elements;
for (; begin != end; ++begin)
{
bool could_insert = visited_elements.insert(*begin).second;
if (!could_insert) return begin;
}
return end;
}
#include <iostream>
int main()
{
int test[] = {8, 10, 3, 4, 1, 1, 1, 1};
int* end = test + sizeof test / sizeof *test;
int* p = find_repeated_element(test, end);
if (p == end)
{
std::cout << "the was no repeated element\n";
}
else
{
std::cout << "repeated element: " << *p << "\n";
}
}
答案 3 :(得分:0)
由于Pigeon hole principle,您只需要测试数组的前n / 2 + 1个成员,因为某些重复的数字将重复至少两次。循环遍历每个成员,使用哈希表来跟踪,并在有重复两次的成员时停止。
答案 4 :(得分:0)
O(n)的另一种解决方案(但不完全是n / 2 + 1),但有O(1)空间:
因为您拥有该数字的n / 2,那么如果您将其视为已排序的数组,则会有其位置的场景:
要么它是最低的数字,所以它需要1-n / 2的位置..或者它不是,然后肯定它位于n / 2 + 1的位置。
因此,您可以使用selection algorithm并检索4个元素:范围[(n / 2-1),(n / 2 + 1)]的大小
我们想要数字k的大小,所以这对算法没问题。
然后,在这4个数字中,重复的数字必须至少两次(简单检查)
总复杂度:4 * O(n)+ O(1)= O(n)
答案 5 :(得分:0)
关于复杂度O(n / 2 + 1)和空间复杂度O(1),您可以(几乎)满足这种方法的要求:
比较元组:
a [x] == a [x + 1],a [x + 2] == a [x + 3] ... a [n-1] == a [n]
如果找不到匹配,则增加步骤:
a [x] == a [x + 2],a [x + 1] == a [x + 3]
在最坏的情况下,当你有这样的数组时,这将在O(n / 2 + 2)中运行(但总是在O(1)空间中):[8 1 10 1 3 1 4 1]
答案 6 :(得分:-2)
qsort( )
数组扫描第一次重复。