lintcode 容易题:Permutation Index 排列序号

题目:

排列序号

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

样例

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

解题:

这个题目感觉很坑的。感觉这只有求出所有的排列,然后找出其对应的下标,但是怎么求出排列,在做Project Euler 时候碰到过,但是现在我又不会写了,那时候毕竟是抄别人的程序的。在geekviewpoint看到一种很厉害的解法,不需要求所有的排列,直接根据给的数组进行求解。

思路:

1.对于四位数:4213 = 4*100+2*100+1*10+3

2.4个数的排列有4!种。当我们知道第一位数的时候,还有3!种方式,当知道第二位数时候还有2!种方式,当知道第三位数的时候还有1!种方式,前面三位数都确定的时候,最后一位也确定了。<这里是按照高位到地位的顺序>

3.对4个数的排列,各位的权值为:3!,2!,1!,0!。第一位之后的数小于第一位的个数是x,第二位之后的数小于第二位的个数是y,第三位之后的数小于第三的个数是z,第四位之后的数小于第四位的个数是w,则abcd排列所在的序列号:index = x*3!+y*2!+z*1!,<0!=0>

在数的排列中,小数在前面,大数在后面,所以考虑该位数之后的数小于该为的数的个数,这里我自己理解的也不是很透,就这样。

4.例如 4213;x= 3,y = 1,z=0,index = 18+2=20

123;x = 0,y=0,index = 0

321;x= 2,y=1,index = 2*2!+1*1! = 5

这里的下标是从0开始的。

Java程序:

public class Solution {
    /**
     * @param A an integer array
     * @return a long integer
     */
    public long permutationIndex(int[] permutation) {
        // Write your code here
    long index = 0;
    long position = 2;// position 1 is paired with factor 0 and so is skipped
    long factor = 1;
    for (int p = permutation.length - 2; p >= 0; p--) {
        long successors = 0;
        for (int q = p + 1; q < permutation.length; q++) {
            if (permutation[p] > permutation[q]) {
                successors++;
            }
        }
    index += (successors * factor);
    factor *= position;
    position++;
    }
    index = index + 1;
    return index;
    }
}

总耗时: 5756 ms

Python程序:

class Solution:
    # @param {int[]} nums an integer array
    # @return {long} a long integer
    def permutationIndex(self, nums):
        # Write your code here
        index = 0
        position  = 2
        factor = 1
        numslen = len(nums)
        for i in range((numslen-2),-1,-1):
            successors = 0
            for j in range((i+1),numslen):
                if nums[i]>nums[j]:
                    successors+=1
            index += successors*factor
            factor*=position
            position+=1
        index +=1
        return index

总耗时: 223 ms

同时,九章上面的程序还看不懂。。。

时间: 2024-10-17 16:01:21

lintcode 容易题:Permutation Index 排列序号的相关文章

LintCode &quot;Permutation Index II&quot; !

Simply a variation to "Permutation Index". When calculating current digit index, we consider duplicated case. Again, similar as "Digit Counts", it is another counting problem and stil digit by digit. And please note: we can use Fenwick

Permutation Index I &amp; II

Given a permutation which contains no repeated number, find its index in all the permutations of these numbers, which are ordered in lexicographical order. The index begins at 1. Example Given [1,2,4], return 1. 分析:http://www.cnblogs.com/EdwardLiu/p/

【mysql 】mysql 获取排列序号

在进入正题之前先来了解一个mysql中的小知识点: ①   := 与 = 的区别 :=   赋值的意思.在set update select 中表示赋值的意思,用的比较少一般都用=,但是在用变量实现行号时(比如本文标题获取排列序号),一定要用:=. =   等于的意思,只有当set 和 update时,和:=的意思是一样的,表示赋值,其余情况都是等于的意思. ② 用户变量 @ @rank 是对一个叫rank的参数进行赋值.对用户变量赋值有两种方式,一种直接用"="另一种用":

lintcode 中等题:next permutation下一个排列

题目 下一个排列 给定一个整数数组来表示排列,找出其之后的一个排列. 样例 给出排列[1,3,2,3],其下一个排列是[1,3,3,2] 给出排列[4,3,2,1],其下一个排列是[1,2,3,4] 注意 排列中可能包含重复的整数 解题 和上一题求上一个排列应该很类似 1.对这个数,先从右到左找到递增序列的前一个位置,peakInd 2.若peakInd = -1 这个数直接逆序就是答案了 3.peakInd>= 0 peakInd这个位置的所,和 peakInd 到nums.size() -1

【LeetCode每天一题】Permutation Sequence(排列序列)

The set [1,2,3,...,n] contains a total of n! unique permutations.By listing and labeling all of the permutations in order, we get the following sequence for n = 3: "123" "132" "213" "231" "312" "321&q

Lintcode: Permutation Index

Given a permutation which contains no repeated number, find its index in all the permutations of these numbers, which are ordered in lexicographical order. The index begins at 1. 在计算最终的 index 时需要动态计算某个数的相对大小.我们可通过两重循环得出到某个索引处值的相对大小. 正确 以4,1,2为例,4为第3大

LintCode数组题总结

做算法题的时候,几乎不可避免要跟数组打交道.在LintCode上数组那一章有这么一些题目: 1)547. Intersection of Two Arrays 比较简单.要求找到2个数组的交集,简单点的方法就是用2个hashSet,第一个HashSet存第一个数组的元素.然后扫描第二个数组,如果第二个数组中的元素在第一个HashSet中出现了,那么就把它加到第二个HashSet中.最后第二个HashSet就是两个数组的交集了. 2)138. Subarray Sum 要求在一个数组中找到一个子数

lintcode 中等题:continuous subarray sum 联系子数组之和

题目 连续子数组求和 给定一个整数数组,请找出一个连续子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的值.(如果两个相同的答案,请返回其中任意一个) 样例 给定 [-3, 1, 3, -3, 4], 返回[1,4]. 解题 法一:直接暴力,时间复杂度O(N2),时间超时 public class Solution { /** * @param A an integer array * @return A list of integers includes the i

LintCode刷题笔记-- LongestCommonSquence

题目描述: Given two strings, find the longest common subsequence (LCS). Your code should return the length of LCS. 解题思路: 这一题是非常经典的动态规划问题,在解题思路上可以按照经典的动态规划的解法,这是在系统学习动态规划之后第一个解决的LintCode上的问题: 1.子问题划分 给出两个字符串的A,B,两个字符串长度分别为lenA,lenB,求出两个字符串的LCS: 这划分为子问题:A.