找到一百万个元素中唯一的唯一元素

时间:2016-06-03 22:15:38

标签: java arrays

在最近的一次采访中我被问到这个问题。

您将获得一个包含一百万个元素的数组。所有元素都是重复的,除了一个。我的任务是找到独特的元素。

var arr = [3, 4, 3, 2, 2, 6, 7, 2, 3........]

我的方法是在for循环中遍历整个数组,然后创建一个map,索引为数组中的numbervalue为数组中出现的数字的frequency。然后再次遍历我们的地图并返回值为1的索引。

我说我的方法需要O(n)时间复杂度。面试官告诉我要以低于O(n)的复杂度对其进行优化。我说我们不能,因为我们必须通过一百万个元素来完成整个阵列。

最后,他似乎并不满意并转向下一个问题。

我理解在数组中经历数百万个元素是昂贵的,但是如果不对整个数组进行线性扫描,我们怎么能找到一个独特的元素呢?

PS:数组未排序。

4 个答案:

答案 0 :(得分:15)

我确信你不能在不经过整个数组的情况下解决这个问题,至少如果你没有任何附加信息(比如元素被排序并限制为某些值),那么问题就出现了O(n)的最小时间复杂度。但是,您可以使用基于XOR的解决方案将内存复杂度降低到O(1),如果每个元素都在数组中偶数次,这似乎是问题的最常见变体,如果是您对此感兴趣:

int unique(int[] array)
{
    int unpaired = array[0];
    for(int i = 1; i < array.length; i++)
        unpaired = unpaired ^ array[i];
    return unpaired;
}

基本上,每个XORed元素都会与另一个元素取消,因此您的结果是唯一没有取消的元素。

答案 1 :(得分:1)

假设阵列未被排序,则不能。每个值都与下一个值相互排斥,因此无法推断出任何其他值的值都没有?

如果它是一个有序的值数组,那么这是另一个问题,完全取决于使用的顺序。

我同意最简单的方法是使用另一个容器并存储值的频率。

答案 2 :(得分:1)

事实上,由于数组中的元素数量已经修复,你可以做得比你提出的要好得多。

通过“创建一个map,索引作为数组中的数字,值作为数组中出现的数字的频率”,创建一个具有2 ^ 32个位置的地图(假设数组有32个-bit整数),然后你必须通过该映射来找到其值为1的第一个位置。这意味着你正在使用一个大的辅助空间,在最坏的情况下,你正在做 10 ^ 6 + 2 ^ 32 操作(一百万来创建地图和2 ^ 32找到元素。)

您可以使用某种n*log(n)算法对数组进行排序,然后在排序数组中搜索元素,而不是这样做,因为在您的情况下,n = 10^6

例如,使用合并排序,您将使用一个小得多的辅助空间(只是一个10 ^ 6整数的数组),并且可以执行大约(10 ^ 6)* log(10 ^ 6)+ 10 ^ 6个操作排序然后找到元素,大约 21 * 10 ^ 6 (比10 ^ 6 + 2 ^ 32多许多倍)。

PS:对数组进行排序会使搜索从二次成本减少到线性成本,因为对于排序数组,我们只需要访问相邻位置来检查当前位置是否唯一。

答案 3 :(得分:0)

你的方法似乎很好。可能是他正在寻找一个边缘情况,其中数组的大小是均匀的,这意味着没有不匹配的元素或者有两个或更多。他只是错误地问它。