我们记录每一位比他小的个数,比如对于adcb,在a没有数能比他小,在d,能找到2个比他小的数(b, c),在c,能找到一个比他小的数(b),d是最后一位数,所以没有比他小的数,因为已经没有数能给我们选择了。 每有一个比当前数小的数,即代表在这一位,能有n * x!的组合的数比当前数小(n = 有几个小的数,x = 当前的index),比如对于d,有bc比他小(n = 2, x = 2),所以有abcd, abdc, acbd, acdb比adXX要小,2 * 2! 我们可以用binary index tree 来记录比当前位小的数。
Solution:
Time: O (n) Space: O (n)
public class Solution { public static class BIT { int[] arr;
public BIT(int n) { this.arr = new int[n + 1]; }
public void update(int i, int v) { // update nodes that include i in left subtree i = i + 1; while (i <= this.arr.length) { this.arr[i] += v; i += i & (-i); } }
public int sum(int i) { // sum up left sub trees smaller than i int sum = 0; i = i + 1; while (i > 0) { sum += this.arr[i] % 1000003; i -= i & (-i); } return sum; } }
private int[] factorial(int n) { int[] arr = new int[n + 1]; arr[0] = 1; for (int i = 1; i < arr.length; i ++) { arr[i] = (arr[i - 1] * i) % 1000003; } return arr; }
*/ for (int i = 0; i < arr.length; i ++) { int c = arr[i]; bit.update(c, 1); } int rank = 1; for (int i = 0; i < arr.length; i ++) { int c = arr[i]; int smallerCount = bit.sum(c) - 1; // System.out.println(arr[i] + " " + smallerCount + " " + factorial[arr.length - i - 1]); rank += smallerCount * factorial[arr.length - i - 1]; bit.update(c, -1); } return rank % 1000003; } }