计算数组的回文排列“镜像”

问题描述

我一直在为这个问题寻找解决方案:

给定一个整数数组,计算回文(“镜像”)的不同排列;也就是说,找到数组元素可以重新排列的不同方式的数量,以便它们向后和向前读取相同的方式。例如:

  1. 如果数组是 [1,1,2],那么只有一个不同的回文排列(即 [1,2,1]),所以期望的结果是 1。
  2. 如果数组是[1,2],那么有两个不同的回文排列(即[1,1]和[2,2]),所以需要结果是 2。
  3. 如果数组是 [2,3,3],则有两个不同的回文排列(即 [3,3] 和 [2,2 ]),所以期望的结果是 2。

我一直在尝试解决这个问题,但卡住了很长时间,在网上找不到任何解决方案。任何帮助将不胜感激(刚开始使用算法和 ds 的东西)

我的想法是找到该数组的中位数的索引(例如,在示例#1 中,中位数位于索引 1)并将其后面的所有数字移动到它之前(因此,[1,1] ),并使用两个指针(一个在结尾,一个在开头)检查所有数字是否相等。

但是,如果假设 #1 是 arr = [1,2],这将不起作用,因为执行上述操作将等于 1,2。在这种情况下,我应该做的是将 1 移动到 2s 之间(如果有意义的话,就是从末尾开始的中位数)。有点像上面的方法,但相反(?)

解决方法

这里是总体思路:

  1. 计算每个唯一值出现的频率。

  2. 如果数组的长度是奇数,那么正好有一个频率应该是奇数。如果没有,就没有镜子。如果是这样,则必须将该值放置在中心。然后,镜像的数量等于您从数组中获得的数量少一个值 - 那个值被删除。

  3. 现在数组长度是偶数。没有频率应该是奇数,否则就没有镜子。现在将所有这些频率减半。

  4. 确定可以用这些值及其(减半)频率形成多少排列。 formula 是:

    ?! / (?1!?2!?3!...??!)

    其中 ? 是所有(减半)频率的总和(即数组大小的一半),而 ?? 是(减半)频率的列表。