两个阵列是否相互排列?

时间:2012-06-07 09:31:30

标签: algorithm math

  

可能重复:
  Check if array B is a permutation of A

给出2个大小相等的未排序整数数组ab。确定b是否为a的排列。是否可以在O(n) timeO(1) space

中完成此操作

我想到的第一个解决方案是使用XOR,即XOR all the elements of a and b and if the resultant is 0 which means that b is a permutation of a。但他给出了这种方法失败的例子。例如 -

a: [1 6 0 0 4] -- b: [1 0 6 1 5]
a: [1 6 0 0 5] -- b: [1 0 6 1 4]

任何人都知道如何在O(n) timeO(1) space中做到这一点?

3 个答案:

答案 0 :(得分:2)

对于有界的整数范围 - 让该范围为[n,m],以便m-n = U您可以使用in place radix sort对数组进行排序,这也在this great post中进行了讨论。

在你有两个排序的数组之后 - 两者上的简单迭代都可以给你答案 - 当且仅当排序的数组相同时,原始数组才是彼此的排列。

注意:
在这个答案中有一些“作弊”[因此我没有发表它,直到OP在评论中提出它...],因为它的时间复杂度是O(nlogU),空格是{{ 1}}。但是,对于有界范围 - 我们可以假设O(logU),对于这些情况,我们会得到O(logU) = O(1)时间和O(n)空格。

答案 1 :(得分:1)

如果你的set元素是非负的,并且你有一个可用的无界整数类型(BigInteger或类似的),你可以在集合A上定义一个函数:

C(A) = product(p_(a+1)))

中的每个a

A

其中p_nn素数。然后C仅取决于A中的,而不是它们的顺序;并且对值的任何更改都会更改C

例如,

C([1 6 0 0 4]) = p_2.p_7.p_1.p_1.p_5 = 3.17.2.2.11 = 2244

(显然,任何具有相同元素的集都具有相同的C,无论顺序如何),

C([1 6 0 1 4]) = p_2.p_7.p_1.p_2.p_5 = 3.17.2.3.11 = 3366

所以我们知道这些集合是不同的。这使用了算术的基本定理,该定理指出任何大于1的整数都可以写成素数的唯一乘积(直到因子的排序)。或者它可能使用一个推论。我刚刚制作了这个方法,所以它可能不起作用。这篇文章并不是为了证明其正确性......

答案 2 :(得分:1)

您的独占解决方案基本上是基于散列的解决方案,但使用的是质量差的哈希函数。

你想要的是一个哈希函数......

  1. 使的哈希值不太可能发生冲突,因此可以将它们视为整数的唯一标识符。 Git使用SHA-1哈希来识别源代码版本,碰撞概率很低,可以忽略。

  2. 可交换(如xor和plus)并且可能是关联的,因此项目的顺序不会更改生成的哈希值。

  3. 第二个要求可能是尴尬的。我在谷歌度过了一段时间,但却害怕像“Quasigroup”这样的话。