有效地测试阵列成员资格

时间:2015-05-10 03:51:19

标签: java arrays sorting data-structures

在Java开发人员访谈中,有人问我:

  

给定两个整数数组,打印出第一个数组中第二个数组中不存在的值。总时间复杂度应为 O n )。

我提出的方法是:

  1. 使用哈希表存储第二个数组的值。
  2. 现在检查哈希表中是否存在第一个数组的值。如果没有,请打印值。
  3. 还有其他更有效的方法来实现吗?

1 个答案:

答案 0 :(得分:1)

我们假设两个数组的长度大致相同,因此 n 用于描述它们的长度。 (否则我们需要引入一个新变量。)

备选方案概述:

线性搜索:如果我们将第二个数组存储为未排序的数组/列表,那么每次搜索都需要 O n )时间,总时间 O n 2 )。

二进制搜索:如果我们对第二个数组进行排序,则需要 O n log n )时间。每个查询都需要 O (log n )时间,总计 O n log n )时间。

平衡树:如果我们将第二个数组存储在TreeSet中,则每次搜索都需要 O (log n )时间总计 O n log n )时间。

哈希表:如果我们将第二个数组存储在您提到的HashSet中,则每次插入都需要 O (1)摊销时间并且每次搜索都需要 O (1)时间,总共 O n )时间。

位向量:如果我们创建一个2 32 元素位向量来覆盖所有可能的Java intInteger值,我们可以添加第二个数组的每个元素并测试 O (1)时间内是否存在值,总共 O n )想要的时间。然而,对于2 32 元素的初始化,存在非常昂贵的常数项。

下限参数:第二个数组的长度为 O n )。如果我们没有扫描整个阵列,就不可能准确地判断某个值是否在第二个数组中。因此,解决此问题的绝对最短时间是Ω( n )。这意味着 O n )是我们可能做的最好的事情。