我想对有几次递增运行的排列进行排序。递增运行是以下形式的排列元素序列 perm[i] < perm[i+1]
. 约束条件是 perm[i+1] - perm[i] <= maxDistance
增加跑步次数。索引处的转折点 i
描述如下: perm[i-1] > perm[i]
.
例子 1234
, maxDistance = 2
, turning point at index 2
有效排列: 1324
, 2413
, 3412
无效的置换: 1423
更大的最大距离 1243
指数3的转折点
这是我的尝试:这给了我等级 1
为了 1324
,排名 3
为了 2413
,排名 4
为了 3412
但排名从0开始。但我不知道为什么军衔不是 0,1,2
. 如何对这种排列进行排序?先谢谢你。
public BigInteger calcRank(int[] perm, int maxDistance){
BigInteger rank = BigInteger.ZERO;
BigInteger multipler = BigInteger.ONE;
List<Integer> turns = calcTurns(perm);
int[] numbers = getNumbers(perm.length);
for(int j=0,last=-1,q=0;j<perm.length && j<turns.get(turns.size()-1);j++){
int all=0;
int avail=0;
if(j == turns.get(q)){
for(int l=0;l<numbers.length;l++){
if(numbers[l] != -1){
last = l;
break;
}
}
q++;
}
for(int k=last,org=last;k < numbers.length;k++){
if(numbers[k] == -1){
continue;
}
if(all == maxDistance || numbers[org]+maxDistance < numbers[k]){
break;
}
if(numbers[k] == perm[j]){
avail = all;
numbers[k] = -1;
for(int l=k+1;l<numbers.length;l++){
if(numbers[l] != -1){
last = l;
}
}
}
all++;
}
rank = rank.add(multipler.multiply(BigInteger.valueOf(avail)));
multipler = multipler.multiply(BigInteger.valueOf(all));
}
return rank;
}
private List<Integer> calcTurns(int[] perm){
List<Integer> out=new ArrayList<>();
out.add(0);
for(int i=1;i<perm.length;i++){
if(perm[i-1] > perm[i]){
out.add(i);
}
}
return out;
}
private int[] getNumbers(int n){
int[] out = new int[n];
for(int i=1; i <= n;i++){
out[i-1] = i;
}
return out;
}
暂无答案!
目前还没有任何答案,快来回答吧!