Given a string, find its rank among all its permutations sorted lexicographically. For example, rank of “abc” is 1, rank of “acb” is 2, and rank of “cba” is 6.
Input : str = "acb" Output : Rank = 2 Input : str = "string" Output : Rank = 598 Input : str = "cba" Output : Rank = 6
For simplicity, let us assume that the string does not contain any duplicated characters.
One simple solution is to initialize rank as 1, generate all permutations in lexicographic order. After generating a permutation, check if the generated permutation is same as given string, if same, then return rank, if not, then increment the rank by 1. The time complexity of this solution will be exponential in worst case. Following is an efficient solution.
Let the given string be “STRING”. In the input string, ‘S’ is the first character. There are total 6 characters and 4 of them are smaller than ‘S’. So there can be 4 * 5! smaller strings where first character is smaller than ‘S’, like following
R X X X X X
I X X X X X
N X X X X X
G X X X X X
Now let us Fix S’ and find the smaller strings staring with ‘S’.
Repeat the same process for T, rank is 4*5! + 4*4! +…
Now fix T and repeat the same process for R, rank is 4*5! + 4*4! + 3*3! +…
Now fix R and repeat the same process for I, rank is 4*5! + 4*4! + 3*3! + 1*2! +…
Now fix I and repeat the same process for N, rank is 4*5! + 4*4! + 3*3! + 1*2! + 1*1! +…
Now fix N and repeat the same process for G, rank is 4*5! + 4*4! + 3*3! + 1*2! + 1*1! + 0*0!
Rank = 4*5! + 4*4! + 3*3! + 1*2! + 1*1! + 0*0! = 597
Note that the above computations find count of smaller strings. Therefore rank of given string is count of smaller strings plus 1. The final rank = 1 + 597 = 598
Below is the implementation of above approach:
The time complexity of the above solution is O(n^2). We can reduce the time complexity to O(n) by creating an auxiliary array of size 256. See following code.
The above programs don’t work for duplicate characters. To make them work for duplicate characters, find all the characters that are smaller (include equal this time also), do the same as above but, this time divide the rank so formed by p! where p is the count of occurrences of the repeating character.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
- Lexicographic rank of a string using STL
- Lexicographic rank of a string with duplicate characters
- Find a string in lexicographic order which is in between given two strings
- Generating distinct subsequences of a given string in lexicographic order
- Power Set in Lexicographic order
- Print all permutations in sorted (lexicographic) order
- String slicing in Python to check if a string can become empty by recursive deletion
- Minimal moves to form a string by adding characters or appending string itself
- Lexicographically smallest string formed by appending a character from the first K characters of a given string
- Create a new string by alternately combining the characters of two halves of the string in reverse
- Find the character in first string that is present at minimum index in second string
- Minimum deletions from string to reduce it to string with at most 2 unique characters
- Find the count of palindromic sub-string of a string in its sorted form
- Find length of longest subsequence of one string which is substring of another string
- Decode an Encoded Base 64 String to ASCII String