比较两个长度相同的整数数组

时间:2010-03-08 15:12:51

标签: arrays algorithm

[描述]给定两个长度相同的整数数组。设计一种能够判断它们是否相同的算法。 “相同”的定义是,如果这两个数组按排序顺序排列,则相应位置的元素应该相同。

[Example]
<1 2 3 4>  = <3 1 2 4>
<1 2 3 4> != <3 4 1 1>

[限制]算法应该需要恒定的额外空间和O(n)运行时间。

12 个答案:

答案 0 :(得分:14)

(面试问题可能过于复杂。)

(您可以使用O(N)时间来检查min,max,sum,sumsq等是否相等。)

使用no-extra-space radix sort对两个阵列进行就地排序。 O(N)时间复杂度,O(1)空间。

然后使用通常的算法比较它们。 O(N)时间复杂度,O(1)空间。

(提供的(最大 - 最小)数组是O(N k ),有限k。)

答案 1 :(得分:4)

您可以尝试一种概率方法 - 将数组转换为某个巨大基数B中的数字,并将其转换为某些素数P,例如对所有B^a_i求和i } mod一些大问题P。如果他们都出现了相同的数字,请再次尝试尽可能多的素数。如果在任何尝试中都是假的,那么它们就不对了。如果他们通过了足够的挑战,那么他们是平等的,具有高概率

B&gt;有一个简单的证明。 NP&gt;最大的数字。所以必须有一个无法满足的挑战。这实际上是确定性方法,尽管复杂性分析可能更难,取决于人们如何根据输入的大小来查看复杂性(而不仅仅是元素的数量)。

答案 2 :(得分:3)

我声称:除非指定了输入范围,否则在即时额外空间和O(n)运行时间内解决是不可能的。

我很高兴被证明是错的,所以我可以学到新的东西。

答案 3 :(得分:2)

  1. 将第一个数组中的所有元素插入哈希表
  2. 尝试将第二个数组中的所有元素插入到相同的哈希表中 - 对于每个元素的插入都应该已经存在
  3. 好吧,这不是一个额外的空间,但我现在最好能出现:-)。是否对该问题施加了任何其他约束,例如可能包含在数组中的最大整数?

答案 4 :(得分:2)

一些答案​​基本上是正确的,即使它们看起来不像。哈希表方法(例如)具有基于所涉及的类型的范围的上限而不是数组中的元素的数量。至少通过大多数定义,使得(上限)空间保持不变,尽管常数可能非常大。

理论上,您可以将其从上限更改为真正的恒定空间量。例如,如果你使用的是C或C ++,并且它是char的数组,你可以使用类似的东西:

size_t counts[UCHAR_MAX];

由于UCHAR_MAX是常量,因此数组使用的空间量也是常量。

编辑:我注意到记录中所涉及的项目的范围/大小的界限隐含在算法复杂性的几乎所有描述中。例如,我们都“知道”Quicksort是一种O(N log N)算法。但是,如果我们假设比较和交换正在排序的项目需要恒定的时间,这是唯一的,只有在我们绑定范围时才能成立。如果涉及的项目范围足够大以至于我们不能再将比较或交换视为占用恒定时间,则其复杂性将变为类似O(N log N log R),R是范围,因此{{ 1}}近似表示项目所需的位数。

答案 5 :(得分:1)

这是一个棘手的问题吗?如果作者假设整数在给定范围内(2 ^ 32等),则“额外恒定空间”可能只是一个大小为2 ^ 32的数组,您可以在其中计算两个列表中的出现次数。

如果整数未排列,则无法完成。

答案 6 :(得分:0)

您可以使用以下规则将每个元素添加到散列映射&lt; Integer,Integer&gt;中:数组A是加法器,数组B是移除器。从数组A插入时,如果该键不存在,请插入值为1.如果该键存在,则递增该值(保持计数)。删除时,如果密钥存在且大于1,则将其减1.如果密钥存在且为1,则删除该元素。

使用上面的规则运行数组A,然后运行数组B.如果在删除阶段期间的任何时间,阵列B没有找到元素,则可以立即返回false。如果在加法器和移除器都完成后,hashmap为空,则数组是等效的。

编辑:哈希表的大小将等于数组中不同值的数量,这是否符合常量空间的定义?

答案 7 :(得分:0)

我认为解决方案需要某种转换,它既是关联的又可交换的,并保证了一组独特的输入的独特结果。但是我不确定这是否存在。

答案 8 :(得分:0)

public static boolean match(int[] array1, int[] array2) {

        int x, y = 0;

        for(x = 0; x < array1.length; x++) {
                y = x;
                while(array1[x] != array2[y]) {
                        if (y + 1 == array1.length)
                                return false;
                        y++;
                }
                int swap = array2[x];
                array2[x] = array2[y];
                array2[y] = swap;
        }

        return true;
}

答案 9 :(得分:-1)

对于每个数组,使用Counting排序技术来构建小于或等于特定元素的元素数。然后在每个索引处比较两个构建的辅助阵列,如果它们等于数组r等于否则它们不相等。字符串排序需要O(n),并且每个索引处的数组比较再次为O(n),因此它的O(n)和所需空间完全等于两个数组的大小。以下是计算排序http://en.wikipedia.org/wiki/Counting_sort的链接。

答案 10 :(得分:-1)

给定int在-n .. + n范围内检查权益的简单方法可能是以下(伪代码):

// a & b are the array
accumulator = 0
arraysize = size(a)
for(i=0 ; i < arraysize; ++i) {
  accumulator = accumulator + a[i] - b[i]
  if abs(accumulator) > ((arraysize - i) * n) { return FALSE }
}
return (accumulator == 0)

累加器必须能够存储范围= + - arraysize * n

的整数

答案 11 :(得分:-1)

怎么回事 - 对两个阵列中的所有数字进行异或。如果结果为0,则表示您匹配。