有一个n个数字的数组。一个数字重复n / 2次,其他n / 2个数字不同

时间:2011-06-23 07:52:12

标签: c++ arrays programming-languages

有一个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)。

7 个答案:

答案 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( )数组扫描第一次重复。