有一个由n个数字组成的数组.一个数字重复n/2次,而其他n/2个数字是不同的
There is an array of n numbers. One number is repeated n/2 times and other n/2 numbers are distinct
有一个由n个数字组成的数组。一个数字重复n/2次,而其他n/2个数字是不同的。找出重复的数字。(最佳解决方案是o(n)恰好是n/2+1比较。)
这里的主要问题是n/2+1比较。我有两个O(n)的解,但它们进行了n/2+1以上的比较。
1> 把数组的个数分成三组。对任何相同的元素,把那n/3组分成。例如数组是(1 10 3)(4 8 1)(1 1)。。。。因此所需的比较次数为7,即大于n/2+1即8/2+1=5
2> 将a[i]与a[i+1]和a[i+2]进行比较例如阵列是8 10 3 4 1 1 1
总共9个比较
我很感激哪怕是一点点帮助。谢谢
空间复杂度为O(1)。
当然,如果其他所有对都不同,则只需比较所有对。如果你找到一对有两个相等数字的,你就得到了这个数字
假设你有这样的数字(这只是关于索引)
[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个比较。
您只需要找到数组中存在两次的数字。
你只是从头开始,保留一个哈希或你已经看到的数字,当你得到一个出现两次的数字时,就停止。
最糟糕的猫场景:你首先看到所有n/2个不同的数字,然后下一个数字是重复的n/2+2(因为您要查找的数字不是n/2唯一数字的一部分)
阅读关于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 elementn";
}
else
{
std::cout << "repeated element: " << *p << "n";
}
}
由于Pigeon-hole原理,您只需要测试数组的前n/2+1个成员,因为某些重复次数将至少重复两次。循环遍历每个成员,使用哈希表进行跟踪,并在某个成员重复两次时停止。
O(n)(但不完全是n/2+1)的另一个解决方案,但具有O(1)空间:
因为你有这个数字的n/2,所以如果你把它看作一个排序的数组,它的位置有两个场景:
要么它是最低的数字,所以它将占据1-n/2的位置。。或者它不是,然后确定它在位置n/2+1。
因此,您可以使用选择算法,并检索4个元素:大小为[(n/2-1),(n/2+1)]的范围
我们想要k的大小,所以算法可以。
然后,在这4个数字中重复的数字必须至少是两次(简单检查)
所以总复杂度:4*O(n)+O(1)=O(n)
关于复杂性O(n/2+1)和空间复杂性O(1),您可以(几乎)满足这种方法的要求:
比较元组:
a[x]==a[x+1]、a[x+2]==a[g+3]。。。a[n-1]==a[n]
如果未找到匹配项,则增加步骤:
a[x]==a[x+2],a[x+1]==a[g+3]
在最坏的情况下,当您有这样的数组时,这将在O(n/2+2)中运行(但始终在O(1)空间中):[8 1 10 1 3 1 4 1]
qsort( )
阵列然后扫描第一次重复。
- C++问题:用户认为数字1-100,程序提出问题不超过6次即可得到答案。无法正确
- C++ 检查结果数组中有多少次数字
- 如何计算整数链中使用了多少次数字?
- C++:创建1000次唯一的随机分布,在任何分布中都没有重复的数字
- 如何执行此程序,将键入的数字显示为数字值的多次
- 带有文件结束函数的 while 循环重复输出文件中的最后一个数字两次
- C++随机数生成器通常在 Visual Studio 中运行程序时在 2 次后停止生成数字
- 连续两次写入数字时出现逻辑错误 (C++)
- C++:对数组进行排序,最后一个数字重复两次
- 搜索字符串是否至少包含一次从 0 到 9 的所有数字的最有效方法
- 使用二叉搜索查找数字的第 N 次出现的索引
- 快速获取接近2次幂的数字(浮点)
- 如何使用Mersenne Twister生成两个数字之间的所有值一次
- 难以将数字0-12四次分配给52 C 的数组
- 如何直接获取rand()序列中的第n个数字,而不必调用rand(()n次
- 删除向量中数字的单次出现,当数字在反向遍历时出现多次时
- Math和C :如何编写一次函数,其中每16次添加一个数字
- 如何一次读取一个数字并将其存储在数组中,跳过重复项
- 有没有办法将 int 赋入具有递归函数的字符串中,而无需将数字反转两次
- 一次打印 2 个字节的十六进制数字