繁体   English   中英

滑动拼图中反转次数的奇偶性

[英]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]
...

...并分析它,假设我们已经用kk+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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM