点击注册
点击注册
.

怎么理解全排列算法的原理


发布日期:2022-03-27 04:40    点击次数:146


怎么理解全排列算法的原理

我的理解是这样的,首先这个全排列应该是 越到后面 ,就越是大的数在前吧,譬如说 123 的排列,就是 123,132,213,231,312,321 。 那么如果想变大,那就要把大的数放到前面去。所以会要找“降序”的邻居。然后棋牌问答,在前进时棋牌问答,可以将这个数列理解成一个数,那么“下一个排列”计算时就需要两个数之间的差尽可能小,比如说从 123 到 132 就增加了 9,而进一格到 123 的任何其它排列所增加的值都是大于 9 的。因为全排列是越到后面数越大,所以全升序的情况下就没有下一步,所以就要找降序的情况才能进行交换。那么怎么样才能让上升的值变小呢?如果去对高位(前)的数进行交换,那造成的增量就会比对低位(后)的数进行交换更大,所以应该先从后往前找而不是从前往后找。也因为这个原因,找到了这个第一个降序的邻居x[i],x[i+1]的意思也就可以理解为 所有以 x[0...i]这个前缀开头的情况已经走到了最后一步(因为x[i+1]及之后的都是降序了),所以就需要把x[i]增加才能进入下一步。接下来就是决定x[i]应该增加到多少,或说与谁换。举例来说,对于 [0,1,2,5,3,3,0] 的情况,从后往前第一个看到的降序邻居是 [2,5] ,这就说明,这个全排列已经走完了 [0,1,2] 开头的所有情况,接下来得要是 [0,1,3] 开头了。这里的 i=2,就说明现在的前缀是 x[0:2]。找到了之后,到了第三步,那么从最后面一直看到x[i],其实是先升后降的过程。既然是先升后降那就肯定有一个数会比x[i]要来得大。那为了让第 i 位增加得尽可能小,所以就会从后往前找第一个比x[i]大的数。回到刚才的例子,这里x[2]=2应该与x[5]换,其中x[5]=3。就是说,把前缀从 [0,1,2] 进化到 [0,1,3] 是增量最小的,如果增加到 [0,1,5] 就增加得太多了。在找到了之后,全排列就从 x[0,1,2,3,4 ... i] 这个前缀就更新了,也就是说接下来一段时间内,都是以 [0,1,3] 开始的。以 [0,1,3] 开头的第一个排列,应该是之后的所有元素递增的。但因为恰好在上一个状态,也就是 [0,1,2] 开头时的情况,之后的元素是递减的,而将 2 与 3 进行交换亦不会改变之后的元素的递减的性质,所以 把后面的元素从 递减 变成 递增 就只需要 reverse 一下就可以了。总的来说,给定输入 [0,1,2,5,3,3,0],按楼主的算法,就会在第一步时找到第3、4个元素组成的邻居,[0,1,2,5,3,3,0],i=2,x[i]=2, x[i+1]=5;在第二步时从后往前看到第一个比2大的元素,就是x[5]=3,并与x[2]交换,数组变成[0,1,3,5,3,2,0];在第三步时将第四个元素及其后的元素反向,成为[0,1,3,0,2,3,5]。参考了这篇文章(),不知说清楚了没 (: