如何检查排列是否具有相同的奇偶性?
我正在寻找一种方法来检查 2 个排列(由列表表示)是否相同平价。请注意,我对它们是偶还是奇奇偶校验不感兴趣,只是相等。
我是 Python 新手,下面给出了我的幼稚解决方案作为答复。我期待 Python 专家向我展示一些很酷的技巧,以在更小、更优雅的 Python 代码中实现相同的目标。
I am looking for a way to check if 2 permutations (represented by lists) are of the same parity. Note that I am not interested if they are even or odd parity, just the equality.
I am new to Python and my naive solution is given below as a reply. I am looking forward to Python gurus showing me some cool tricks to achieve the same in lesser, more elegant Python code.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
我的天真的解决方案:
My naive solution:
以下是稍微重构的 Weeble 的答案:
Here's slightly refactored Weeble's answer:
字典的解决方案有问题。
这是调试版本:
唯一的区别是字典中的交换没有正确进行。
The solution with the dictionary is bugged.
This is the debug version:
The only differences is that the swap in the dictionary was not made correctly.
我的直觉告诉我,仅计算两种排列之间的差异就会比从一种排列到另一种排列所需的交换次数多出一个。这反过来会给你平价。
这意味着您根本不需要在代码中进行交换。
例如:
存在三个差异,因此需要两次交换才能将一个置换为另一个,因此您具有偶数奇偶性。
另:
有四个差异,因此有三个交换,因此奇偶校验。
My intuition tells me that, just counting the differences between the two permutations will give you one more than the number of swaps need to get from one to the other. This in turn will give you the parity.
This means that you don't need to do the swaps in your code at all.
For example:
There are three differences, hence two swaps are needed to permute one into the other, hence you have even parity.
Another:
There are four differences, hence three swaps, hence odd parity.
如果我们将两个排列组合起来,当每个排列具有相同的奇偶性时,结果将具有偶奇偶性,如果它们具有不同的奇偶性,则结果将具有奇奇偶性。因此,如果我们解决奇偶校验问题,那么比较两种不同的排列就很简单了。
奇偶性可以通过如下方式确定:选择一个任意元素,找到排列将其移动到的位置,重复直到回到开始的位置。您现在已经找到了一个循环:排列将所有这些元素旋转一个位置。您需要比循环中的元素数少一次交换才能撤消它。现在选择另一个您尚未处理过的元素并重复,直到您看到每个元素。请注意,每个元素总共需要一次交换减去每个周期一次交换。
就排列的大小而言,时间复杂度为 O(N)。请注意,虽然循环中有循环,但内部循环只能对排列中的任何元素迭代一次。
另外,只是为了好玩,这里有一个基于维基百科定义的奇偶校验函数的效率低得多但更短的实现(对于偶数返回 True,对于奇数返回 False):
If we combine both permutations, the result will have even parity when each permutation has the same parity, and odd parity if they have different parity. So if we solve the parity problem it's trivial to compare two different permutations.
Parity can be determined as follows: pick an arbitrary element, find the position that the permutation moves this to, repeat until you get back to the one you started with. You have now found a cycle: the permutation rotates all these elements round by one position. You need one swap less than the number of elements in the cycle to undo it. Now pick another element you haven't dealt with yet and repeat until you've seen every element. Observe that in total you needed one swap per element minus one swap per cycle.
Time complexity is O(N) in the size of the permutation. Note that although we have a loop within a loop, the inner loop can only ever iterate once for any element in the permutation.
Also, just for fun, here's a much less efficient but much shorter implementation of the parity function based on the definition in Wikipedia (returning True for even and False for odd):
这是我对代码的调整
这是它
Here is my tweak of your code
Here is it
上一个答案的一个小变体 - 复制 perm1,并保存数组查找。
A minor variant of the previous answer - copy perm1, and save array lookups.