[英]Parity of the number of inversions in a sliding puzzle
鉴于反转的定义如下
倒转:给定一个棋盘,倒转是任何一对瓷砖 i 和 j,其中 i < j 但当以行优先顺序考虑棋盘时,i 出现在 j 之后(第 0 行,然后是第 1 行,依此类推)。
我有一个像
arr = [1, 20, 6, 4, 22 , 5 , 12 , 3];
和一个计算反转次数的函数:
function getInvCount(arr){
let inv_count = 0;
for(let i=0; i<arr.length-1; i++){
for(let j=i+1; j<arr.length; j++){
if(arr[i] > arr[j]) inv_count++;
}
}
return inv_count;
}
我想要做的是,如果反转次数是奇数,则对数组进行更改,以便它为我提供偶数次反转。
我该怎么做?
事实上(感谢@MattTimmermans 注意到这一点),交换任何一对元素 - 不仅仅是连续的 - 应该在这里工作。
让我们把你的功能...
function getInvCount(arr){
let inv_count = 0;
for(let i=0; i<arr.length-1; i++){
for(let j=i+1; j<arr.length; j++){
if(arr[i] > arr[j]) inv_count++;
}
}
}
arr[0] => compared with arr[1], ..., arr[k], arr[k + 1], ..., arr[k + x], ..., arr[-1]
arr[1] => compared with arr[2], ..., arr[k], arr[k + 1], ..., arr[k + x], ..., arr[-1]
...
arr[k] => compared with arr[k + 1], arr[k + 2], ..., arr[k + x], ..., arr[-1]
arr[k + 1] => compared with arr[k + 2], arr[k + 3], ..., arr[k + x], ..., arr[-1]
...
arr[k + x] => compared with arr[k + x + 1], arr[k + x + 2], ..., arr[-2], arr[-1]
...
...并分析它,假设我们已经用k
和k+x
索引交换了元素。 那是如何改变结果的?
arr[0] => compared with arr[1], ..., arr[k + x], arr[k + 1], ..., arr[k], ..., arr[-1]
arr[1] => compared with arr[2], ..., arr[k + x], arr[k + 1], ..., arr[k], ..., arr[-1]
...
arr[k + x] => compared with arr[k + 1], arr[k + 2], ..., arr[k], ..., arr[-1]
arr[k + 1] => compared with arr[k + 2], arr[k + 3], ..., arr[k], ..., arr[-1]
...
arr[k] => compared with arr[k + x + 1], arr[k + x + 2], ..., arr[-2], arr[-1]
...
嗯,实际上并不多。 前述任一元件arr[k]
仍然与两者相比arr[k]
和arr[k + x]
-只是以不同的顺序(与比较arr[k + x]
先行现在)。 并且在这些之后的任何元素仍然根本不与这些元素进行比较。 所以所有来自先前“状态”的if(arr[i] > arr[j])
检查仍然存在,显然它们的结果是相同的。
唯一改变的比较是在[k, k+x]
范围内。 对于第一行,检查更改的方式如下:
a[k] > a[k + 1] is replaced by a[k + x] > a[k + 1]
a[k] > a[k + 2] is replaced by a[k + x] > a[k + 2]
...
a[k] > a[k + x] is replaced by a[k + x] > a[k]
似乎很难预测这如何影响计数,因为无法保证这些数字有多大。 但是让我们看看对以下行的检查是如何受到影响的:
a[k + 1] > a[k + 2] => the same
a[k + 1] > a[k + 3] => the same
...
a[k + 1] > a[k + x] => a[k + 1] > a[k]
...
现在,我们可以看到只有一对涉及 a[k + 1] 元素的替换检查:
a[k] > a[k + 1] => a[k + x] > a[k + 1]
a[k + 1] > a[k + x] => a[k + 1] > a[k]
这就是关键:不管a[k + 1]
值是多少,这里正好是两个相反的检查。 事实上,对于 k 和 k + x 之间的任何数也是如此。 仅对于a[k + x]
元素,只有一个交换:
a[k] > a[k + x] => a[k + x] > a[k]
这就是为什么,无论您交换哪个数字,差值都是奇数。 “inversion diff”的确切数量将等价于 (x - 1) * 2 + 1,因此对于连续数字严格为 1,对于由单个元素分隔的数字严格为 3,等等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.