【问题标题】:Find the only unique element in an array of a million elements在一百万个元素的数组中找到唯一的唯一元素
【发布时间】:2016-06-03 22:15:38
【问题描述】:

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

给你一个包含一百万个元素的数组。除了一个之外,所有元素都是重复的。我的任务是找到独特的元素。

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

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

我说过我的方法需要O(n) 时间复杂度。面试官告诉我要在低于O(n) 的复杂度内优化它。我说我们不能,因为我们必须遍历包含一百万个元素的整个数组。

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

我知道遍历数组中的数百万个元素很昂贵,但是如果不对整个数组进行线性扫描,我们怎么能找到唯一的元素呢?

PS:数组未排序。

【问题讨论】:

  • 我们对数组还有什么了解吗?排序了吗?我们知道数组中有哪些唯一值吗?您目前花费 2n 时间遍历数组的每个元素,然后是映射的每个键,并且可以通过从映射中删除键来避免第二次循环,因为您注意到重复,但 O(2n) 仍然是 O(n)
  • @AndrewRueckert - 它没有排序。数组只是包含以某种随机顺序重复的所有数字,但只有一个数字不会重复。
  • 您确定他们说的是 O(n) 时间 复杂度,而不是 O(n) 空间 复杂度吗?你知道重复元素有多少个重复项吗?
  • @user2357112 - 他们说的是时间复杂度,而不是在这里处理空间复杂度。重复可能出现任意次数
  • 您必须查看所有 n 个元素(最坏的情况,可能会有其他情况可以扣除)。您查看的最后一个可能表明您当前的候选人是重复的。面试官可能对你的解释和测试不满意。

标签: java arrays


【解决方案1】:

我敢肯定,如果不遍历整个数组,至少如果您没有任何其他信息(例如对元素进行排序并限制为某些值),您将无法解决此问题,所以问题有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 元素都会与另一个元素抵消,因此您的结果是唯一没有抵消的元素。

【讨论】:

    【解决方案2】:

    假设数组是无序的,你不能。每个值都与下一个值互斥,因此无法从任何其他值推断出任何值?

    如果它是一个有序的值数组,那就另当别论了,完全取决于所使用的顺序。

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

    【讨论】:

      【解决方案3】:

      事实上,由于数组中的元素数量是固定的,你可以做得比你建议的要好得多。

      通过“创建一个map,索引作为数组中的数字,值作为数组中数字出现的频率”,您可以创建一个具有 2^32 个位置的映射(假设数组具有 32 位整数),然后您必须通过该映射以找到值为 1 的第一个位置。这意味着您正在使用一个大的辅助空间,并且在最坏的情况下您正在执行 about 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:对数组进行排序将搜索从二次成本降低到线性成本,因为使用排序后的数组,我们只需要访问相邻位置即可检查当前位置是否唯一。

      【讨论】:

        【解决方案4】:

        你的方法看起来不错。可能是他正在寻找数组大小均匀的边缘情况,这意味着要么没有不匹配的元素,要么有两个或更多。他只是问错了方式。

        【讨论】:

          猜你喜欢
          • 2020-02-02
          • 1970-01-01
          • 2013-02-09
          • 2011-02-08
          • 2020-04-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-13
          相关资源
          最近更新 更多