给出2个大小相等的未排序整数数组a
和b
。确定b
是否为a
的排列。是否可以在O(n) time
和O(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) time
和O(1) space
中做到这一点?
答案 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_n
是n
素数。然后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)
您的独占解决方案基本上是基于散列的解决方案,但使用的是质量差的哈希函数。
你想要的是一个哈希函数......
使极的哈希值不太可能发生冲突,因此可以将它们视为整数的唯一标识符。 Git使用SHA-1哈希来识别源代码版本,碰撞概率很低,可以忽略。
可交换(如xor和plus)并且可能是关联的,因此项目的顺序不会更改生成的哈希值。
第二个要求可能是尴尬的。我在谷歌度过了一段时间,但却害怕像“Quasigroup”这样的话。