zoukankan      html  css  js  c++  java
  • lintcode-197-排列序号

    197-排列序号

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

    样例

    例如,排列 [1,2,4] 是第 1 个排列。

    思路

    参考http://www.cnblogs.com/hujunzheng/p/5020211.html
    首先观察一个全排列, 例如:95412 = X

    1. 题目转换成按照字典序,这个全排列之前有多少个全排列。
    2. X的前面的所有全排列中,对于位置1上可以是5, 4, 1, 2任意一个数,而且对应的全排列的基数都是4!个。
    3. 同理位置2, 3, 4, 5对应的基数分别是,3!,2!,1!,0!(0!==0)。
    4. 得到该位置对应的基数后,那么该位置对应多少个可变数字?9所在位置对应的可变数字的个数为4,分别是5,4,1,2;5所在位置对应的可变数字是4,1,2;4所在位置对应的可变数字是1,2,;1所在位置的对应的可变数字:无。2所在位置对应可变数也是无。
    5. 可以得到结论,X全排列某个位置上对应的可变数字的个数 == 这个数后面有多少个比它小的数的个数。
    6. 为了得到某个数后面有多少个比它小的数的个数,我们采用折半插入排序(从后向前插入)。

    首先计算每一位 A[i] 的后面小于它的数的个数 count,而 i 后面又应该有 n-i-1 位,就有 (n-1-i)! 种排列的可能,所以在 A[i] 之前的可能排列就有 count * (n-1-i)! 个。
    所以遍历数组,所有元素的 count * (n-1-i)! 之和再加 1 就是当前排列的序号

    code

    class Solution {
    public:
        /**
         * @param A an integer array
         * @return a long integer
         */
        long long permutationIndex(vector<int>& A) {
            // Write your code here
            int size = A.size();
            if (size <= 0) {
                return 0;
            }
    
            long long result = 1, fac = 1, base = 1;
            for (int i = size - 1; i >= 0; i--) {
                int count = 0;
                for (int j = i + 1; j < size; j++) {
                    if (A[j] < A[i]) {
                        count++;
                    }
                }
                result += count * fac;
                fac *= (size - i);
            }
            return result;
        }
    };
    
  • 相关阅读:
    专题3.基金投资与策略(中低风险
    专题1. 投资理财概述与货币市场工具(低风险)
    七.风险防范与风险控制(风险分析)
    八.投资组合与估值
    五.固定收益类产品投资策略(投资分析)
    软考倒计时19天
    前三章
    软考倒计时21天:9大管理工具技术
    软考倒计时22天
    软考倒计时23天
  • 原文地址:https://www.cnblogs.com/libaoquan/p/7298718.html
Copyright © 2011-2022 走看看