VOOZH about

URL: https://www.geeksforgeeks.org/dsa/lexicographic-rank-of-a-string/

⇱ Lexicographic rank of a String - GeeksforGeeks


  • Courses
  • Tutorials
  • Interview Prep

Lexicographic rank of a String

Last Updated : 14 Apr, 2026

Given a string s consisting of distinct lowercase characters, find its rank among all its permutations when sorted lexicographically.

Examples:

Input: s = "acb"
Output: 2
Explanation: If all the permutations of the string are arranged lexicographically they will be "abc", "acb", "bac", "bca", "cab", "cba". From here it can be clearly seen that the rank of s is 2.

Input: s = "string"
Output: 598

Input: s = "cba"
Output: Rank = 6

[Naive Approach] Generating all permutations - O(n * n!) Time and O(n) Space

The idea is to generate all the permutations in lexicographic order and store the rank of the current string. To generate all permutations, we first sort the string and then one by one generate lexicographically next permutation. After generating a permutation, check if the generated permutation is the same as the given string and return the rank of string.

Dry run for s = "bca":

  1. Original = "bca", after sorting the string becomes "abc" and initial rank is 1
  2. First permutation "abc" does not match "bca", next permutation becomes "acb" and rank becomes 2
  3. Second permutation "acb" does not match "bca", next permutation becomes "bac" and rank becomes 3
  4. Third permutation "bac" does not match "bca", next permutation becomes "bca" and rank becomes 4
  5. "bca" matches the original string, so the process stops and final rank = 4

Output
598

[Better Approach] Count Smaller Strings - O(n^2) Time and O(1) Space

We count smaller strings than the given string, and at the end return rank as one plus the count value.

Rank = Count of Smaller + 1
For example, for "cba", the 5 smaller strings are "abc", "acb", "bac", "bca" and "cab" and our result is 5 + 1.

How do we count smaller?

We first find count of smaller strings when the first character is replaced. For example, for "cba", if we fix the first character other than "c", we get 4 smaller strings. Now we do the same thing for second character which means, we count smaller strings when first is "c" and second is smaller than "b". We have 1 such string.

For a better understanding follow the below illustration.

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 

  • g x x x x x
  • r x x x x x
  • i x x x x x
  • n x x x x x

Similarly we can use the same process for the other letters. Fix 's' and find the smaller strings starting 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!

If this process is continued the rank = 4*5! + 4*4! + 3*3! + 1*2! + 1*1! + 0*0! = 597. 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

Follow the steps mentioned below to implement the idea:

  • Iterate through the string from index i = 0 to n - 1.
  • For each character, count how many characters to its right are smaller than the current character.
  • For each such smaller character, calculate how many permutations can be formed with the remaining characters.
  • Add this value to the current rank.
  • After completing the iteration, add 1 to the final rank and return it as the answer.

Output
598

Note: We can avoid repeated computation of factorial by first calculating n! and then successively dividing by (n - i) to obtain the remaining factorial values during iteration.

[Expected Approach] Using Frequency Array - O(n) Time and O(1) Space

Create a frequency array to store character counts and convert it into a cumulative array to efficiently find how many characters are smaller than the current character, updating it after each index during iteration.

Dry run for s = "string":

  • i = 0, character 's', smaller characters are g, i, n, r so count = 4, remaining = 5! = 120, rank becomes 1 + (4 × 120) = 481
  • i = 1, character 't', smaller characters are g, i, n, r so count = 4, remaining = 4! = 24, rank becomes 481 + (4 × 24) = 577
  • i = 2, character 'r', smaller characters are g, i, n so count = 3, remaining = 3! = 6, rank becomes 577 + (3 × 6) = 595
  • i = 3, character 'i', smaller character is g so count = 1, remaining = 2! = 2, rank becomes 595 + (1 × 2) = 597
  • i = 4, character 'n', smaller character is g so count = 1, remaining = 1! = 1, rank becomes 597 + (1 × 1) = 598
  • i = 5, character 'g', smaller characters = 0, remaining = 0! = 1, rank remains 598

Output
598

Note: 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. 

Comment