您的位置:首页 > 其它

lintcode-197 排列序号

2017-08-09 00:00 211 查看
原题连接:http://www.lintcode.com/zh-cn/problem/permutation-index/

排列序号

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

样例

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

/**
* @create 2017-08-03 9:57
*/
public class Main {
public static long permutationIndex(int[] A) {
// write your code here
int tag[] = new int[A.length]; //0表示没有计算过,1表示已经计算
long result = 0;

for (int i = 0; i < A.length - 1; i++) {
int small = 0;
for (int j = 0; j < A.length; j++) {
if (A[j] < A[i] && tag[j] == 1) {
small++;
}
}
tag[i] = 1;
result = result + (position(A, A[i]) - small) * f(A.length - i - 1);
}

result++; //最后一位直接加1
return result;
}

public static long f(int n) {
long result = 1;

for (int i = 1; i <= n; i++) {
result *= i;
}

return result;
}

public static int position(int[] A, int target) {
//从0开始
int result = 0;

for (int i = 0; i < A.length; i++) {
if (A[i] < target)  {
result++;
}
}

return result;
}

public static void main(String[] args){
int[] A = {3, 4, 2, 1};
System.out.println(permutationIndex(A));
}
}

函数f(int) 用于计算阶乘,position(int[], int)用于返回某个数在其有序数组中的下标。

ps: 如果只是求某个数在其有序数组中的下标,可以使用快排的思想,此时时间复杂度为O(log(n)), 但快排会改变原来数组中数的位置,如果新创建一个数组复制原来的值,则复杂度又会变为O(n).

对于{3,4, 2, 1},先创建一个tag数组,默认值均为0. 然后进入外层for循环。此时内层的for循环由于条件不满足,什么也不做,small = 0(small表示比A[i]小的元素的个数), 只是令tag[0]=1,表示3这个元素已经访问过。然后计算result = result + (position(A, 3) - 0) * f(4 - 0 - 1) = 0 + (2 - 0)*(3!) = 12. 接下来 result = result + (position(A, 4) - 1) * f(4-1-1) = 12 + (3-1)*(2!)=16, result = result + (position(A, 2) - 0) * f(4-2-1)=16+(1-0)*(1!)=17, 最后一个数不需要进行计算,直接加1即可。

其实理解也不难。

(1,2,3,4), (1,2,4,3), (1,3,2,4), (1,3,4,2), (1,4,2,3), (1,4,3,2)

(2,1,3,4), (2,1,4,3), (2,3,1,4), (2,3,4,1), (2,4,1,3), (2,3,3,1)

(3,1,2,4), (3,1,4,2), (3,2,1,4), (3,2,4,1), (3,4,1,2), (3,4,2,1)

.....

对于{3,4,2,1}中的第一个3, 排在它前面的有12个数,也就是使比它小的数的个数2*(A.length-1)! = 12, 对于第二个4,从首位数字为3开始算它的位置。其实就相当于去掉数字3,计算{4,2,1},重复上述步骤。由于3比4小,去掉3后会影响4在{3,4,2,1}中的位置,所以small=1。(如果去掉的第一个数比4大,则不影响其去掉后4在新的有序数组中的位置)。所以(position(A, A[i]) - small) * f(A.length - i - 1)=(3-1)*f(4-1-1)=4, 剩下同理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  lintcode 排列