关于算法:两个阵列是否相互排列?

Are two arrays permutation of each other?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Check if array B is a permutation of A

给定两个大小相等的非排序整数数组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。但他给出了这种方法失败的例子。例如-

1
2
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中该怎么做吗?


在整数的有界范围的情况下,让这个范围是[n,m],这样m-n = U就可以使用就地基数排序对数组进行排序,这在这篇伟大的文章中也讨论过。

当你有了两个排序的数组之后——对两个数组进行简单的迭代就可以给出答案——如果并且仅当排序的数组是相同的,那么原始数组就是彼此的排列。

注:这个答案中有一些"欺骗"[因此,直到OP在评论中提出要求,我才发表它。],因为它的时间复杂度是O(nlogU),空间复杂度是O(logU)。但是,对于有界范围,我们可以假设O(logU) = O(1),对于这些情况,我们得到O(n)时间和O(1)空间。


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

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

  • 给出极不可能发生冲突的哈希,因此可以将它们作为整数的唯一标识符处理。Git使用sha-1散列来标识源代码版本,冲突的概率非常低,可以忽略。

  • 交换的(像xor和plus),可能是关联的,所以项目的顺序不会改变结果散列。

  • 第二个要求可能是尴尬的。我在谷歌呆过一段时间,但我只是害怕"quasigroup"这样的词。


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

    A中每个AC(A) = product(p_(a+1)))

    其中,p_nn第个质数。那么,C只取决于A中的值,而不是它们的顺序;任何值的变化都会改变C中的值。

    例如,

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

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

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

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