【两次过】Lintcode 197. 排列序号

博客介绍了如何使用康托展开算法计算一个不含重复数字排列的字典序编号。通过样例和公式解释了如何计算排列序号,并提供了具体计算过程。
摘要由CSDN通过智能技术生成

给出一个不含重复数字的排列,求这些数字的所有排列按字典序排序后该排列的编号。其中,编号从1开始。

样例

样例 1:

输入:[1,2,4]
输出:1

样例 2:

输入:[3,2,1]
输出:6

解题思路:

需要知道一个算法:康托展开。

原理介绍
**X = A[0] * (n-1)! + A[1] * (n-2)! + … + A[n-1] * 0! **

A[i] 指的是位于位置i后面的数小于A[i]值的个数,后面乘的就是后面还有多少个数的阶乘

说明 :这个算出来的数康拖展开值,是在所有排列次序 - 1的值,因此X+1即为在全排列中的次序

列 :
在(1,2,3,4,5)5个数的排列组合中,计算 34152的康托展开值。
带入上面的公式

X = 2 * 4! + 2 * 3! + 0 * 2! + 1 * 1! + 0 * 0!
=>X = 61
依次为思路进行写代码:

public class Solution {
    /**
     * @param A: An array of integers
     * @return: A long integer
     */
    public long permutationIndex(int[] A) {
        // write your code here
        long res = 1;   //结果
        long len = A.length;    //标记当前元素后面还剩多少元素
        
        for(int i=0; i<A.length; i++){
            long times = 0; //记录当前元素后面有多少是小于当前元素的
            len--;
            
            for(int j=i+1; j<A.length; j++)
                if(A[j] < A[i])
                    times++;
            
            //计算len的阶乘
            long temp = 1;
            for(long j=len; j>0; j--)
                temp *= j;
            
            res += times*temp;
        }
        
        return res;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值