Permutation Index
题目描述
given a permutation which contains no repeated number, find its index in all the permutations of these number/characters.
follow up:
has repeated number
解题方法
1
这一题其实跟base number有点像,比如举例356421.
- 对于第一位3, 在它之前的可以有1,2
- 第二位5,在它之前的可以有4,2,1(因为3已经在第二位用了)
- 第三位6,在它之前的可以有4,2,1
- 。。。
而每一位n,在它之前的序列的数量应该是可以替换的数字 * (length - n)!
有重复数字,需要去重
有重复元素就是要去掉重复的排列,排列组合问题,如果我们不在乎n个数字的排列
顺序,那么应该除以n!
所以我们在上面的向右寻找小于自身的数的过程中,要用一个hashmap来记录重复 的数出现的次数,注意
- 自身也要记录
- 对于每个重复的数字,都应该在计算时除以它的出现次数的阶乘
Solution
class Solution:
# @param A : string
# @return an integer
def findRank(self, A):
if not A:
return None
length = len(A)
result = 1
factor = 1
for i in range(length-1, -1, -1):
numSmaller = 0
for j in range(i+1, length):
if A[i] > A[j]:
numSmaller += 1
result += (numSmaller * factor)
factor *= length - i
return result
有重复数字的
class Solution:
# @param A : string
# @return an integer
def findRank(self, A):
if not A:
return None
length = len(A)
result = 1
factor = 1
for i in range(length-1, -1, -1):
dup_dic = {} # 每次都要新建一个新的
numSmaller = 0
dup_dic[A[i]] = 1
for j in range(i+1, length):
# 所有重复数字都要记录,不仅仅是比它小的
if A[j] in dup_dic:
dup_dic[A[j]] += 1
else:
dup_dic[A[j]] = 1
if A[i] > A[j]:
numSmaller += 1
result += (numSmaller * factor / self.dupFactor(dup_dic))
factor *= length - i
return result % 1000003
def dupFactor(self, dup_dic):
result = 1
if not dup_dic:
return result
for num in dup_dic:
val = dup_dic[num]
for i in range(1, val+1):
result *= i
return result