给定一个字符串,可以在按字典顺序排序的所有排列中找到其排名。例如,“ abc”的等级为1,“ acb”的等级为2,而“ cba”的等级为6。
例子:
Input : str[] = "acb"
Output : Rank = 2
Input : str[] = "string"
Output : Rank = 598
Input : str[] = "cba"
Output : Rank = 6
为简单起见,让我们假设该字符串不包含任何重复的字符。
一种简单的解决方案是将等级初始化为1,以字典顺序生成所有排列。生成排列后,检查生成的排列是否与给定的字符串相同,如果相同,则返回等级,如果不相同,则将等级增加1。在最坏的情况下,此解决方案的时间复杂度将是指数级的。以下是有效的解决方案。
让给定的字符串为“ STRING”。在输入字符串,“ S”是第一个字符。共有6个字符,其中4个字符小于“ S”。这样就可以有4 * 5!较小的字符串,其中第一个字符小于“ S”,如下所示
RXXXX X
IXXXX X
NXXXX X
GXXXXX
现在让我们修复S’并找到以’S’开头的较小字符串。
对T重复相同的过程,等级为4 * 5! + 4 * 4! +…
现在修复T并对R重复相同的过程,等级是4 * 5! + 4 * 4! + 3 * 3! +…
现在修复R并为I重复相同的过程,等级为4 * 5! + 4 * 4! + 3 * 3! + 1 * 2! +…
现在修复I并对N重复相同的过程,等级为4 * 5! + 4 * 4! + 3 * 3! + 1 * 2! + 1 * 1! +…
现在修复N,并对G重复相同的过程,等级为4 * 5! + 4 * 4! + 3 * 3! + 1 * 2! + 1 * 1! + 0 * 0!
等级= 4 * 5! + 4 * 4! + 3 * 3! + 1 * 2! + 1 * 1! + 0 * 0! = 597
请注意,以上计算发现了较小字符串。因此,给定字符串的等级是较小字符串加1。最终等级= 1 + 597 = 598
下面是上述方法的实现:
C++
// C++ program to find lexicographic rank
// of a string
#include
#include
using namespace std;
// A utility function to find factorial of n
int fact(int n)
{
return (n <= 1) ? 1 : n * fact(n - 1);
}
// A utility function to count smaller characters on right
// of arr[low]
int findSmallerInRight(char* str, int low, int high)
{
int countRight = 0, i;
for (i = low + 1; i <= high; ++i)
if (str[i] < str[low])
++countRight;
return countRight;
}
// A function to find rank of a string in all permutations
// of characters
int findRank(char* str)
{
int len = strlen(str);
int mul = fact(len);
int rank = 1;
int countRight;
int i;
for (i = 0; i < len; ++i) {
mul /= len - i;
// count number of chars smaller than str[i]
// from str[i+1] to str[len-1]
countRight = findSmallerInRight(str, i, len - 1);
rank += countRight * mul;
}
return rank;
}
// Driver program to test above function
int main()
{
char str[] = "string";
cout << findRank(str);
return 0;
}
// This code is contributed
// by Akanksha Rai
C
// C program to find lexicographic rank
// of a string
#include
#include
// A utility function to find factorial of n
int fact(int n)
{
return (n <= 1) ? 1 : n * fact(n - 1);
}
// A utility function to count smaller characters on right
// of arr[low]
int findSmallerInRight(char* str, int low, int high)
{
int countRight = 0, i;
for (i = low + 1; i <= high; ++i)
if (str[i] < str[low])
++countRight;
return countRight;
}
// A function to find rank of a string in all permutations
// of characters
int findRank(char* str)
{
int len = strlen(str);
int mul = fact(len);
int rank = 1;
int countRight;
int i;
for (i = 0; i < len; ++i) {
mul /= len - i;
// count number of chars smaller than str[i]
// fron str[i+1] to str[len-1]
countRight = findSmallerInRight(str, i, len - 1);
rank += countRight * mul;
}
return rank;
}
// Driver program to test above function
int main()
{
char str[] = "string";
printf("%d", findRank(str));
return 0;
}
Java
// Java program to find lexicographic rank
// of a string
import java.io.*;
import java.util.*;
class GFG {
// A utility function to find factorial of n
static int fact(int n)
{
return (n <= 1) ? 1 : n * fact(n - 1);
}
// A utility function to count smaller
// characters on right of arr[low]
static int findSmallerInRight(String str, int low,
int high)
{
int countRight = 0, i;
for (i = low + 1; i <= high; ++i)
if (str.charAt(i) < str.charAt(low))
++countRight;
return countRight;
}
// A function to find rank of a string in
// all permutations of characters
static int findRank(String str)
{
int len = str.length();
int mul = fact(len);
int rank = 1;
int countRight;
for (int i = 0; i < len; ++i) {
mul /= len - i;
// count number of chars smaller
// than str[i] from str[i+1] to
// str[len-1]
countRight = findSmallerInRight(str, i, len - 1);
rank += countRight * mul;
}
return rank;
}
// Driver program to test above function
public static void main(String[] args)
{
String str = "string";
System.out.println(findRank(str));
}
}
// This code is contributed by Nikita Tiwari.
Python
# Python program to find lexicographic
# rank of a string
# A utility function to find factorial
# of n
def fact(n) :
f = 1
while n >= 1 :
f = f * n
n = n - 1
return f
# A utility function to count smaller
# characters on right of arr[low]
def findSmallerInRight(st, low, high) :
countRight = 0
i = low + 1
while i <= high :
if st[i] < st[low] :
countRight = countRight + 1
i = i + 1
return countRight
# A function to find rank of a string
# in all permutations of characters
def findRank (st) :
ln = len(st)
mul = fact(ln)
rank = 1
i = 0
while i < ln :
mul = mul / (ln - i)
# count number of chars smaller
# than str[i] fron str[i + 1] to
# str[len-1]
countRight = findSmallerInRight(st, i, ln-1)
rank = rank + countRight * mul
i = i + 1
return rank
# Driver program to test above function
st = "string"
print (findRank(st))
# This code is contributed by Nikita Tiwari.
C#
// C# program to find lexicographic rank
// of a string
using System;
class GFG {
// A utility function to find factorial of n
static int fact(int n)
{
return (n <= 1) ? 1 : n * fact(n - 1);
}
// A utility function to count smaller
// characters on right of arr[low]
static int findSmallerInRight(string str,
int low, int high)
{
int countRight = 0, i;
for (i = low + 1; i <= high; ++i)
if (str[i] < str[low])
++countRight;
return countRight;
}
// A function to find rank of a string in
// all permutations of characters
static int findRank(string str)
{
int len = str.Length;
int mul = fact(len);
int rank = 1;
int countRight;
for (int i = 0; i < len; ++i) {
mul /= len - i;
// count number of chars smaller
// than str[i] from str[i+1] to
// str[len-1]
countRight = findSmallerInRight(str,
i, len - 1);
rank += countRight * mul;
}
return rank;
}
// Driver program to test above function
public static void Main()
{
string str = "string";
Console.Write(findRank(str));
}
}
// This code is contributed nitin mittal.
PHP
Javascript
C++
// A O(n) solution for finding rank of string
#include
using namespace std;
#define MAX_CHAR 256
// A utility function to find factorial of n
int fact(int n)
{
return (n <= 1) ? 1 : n * fact(n - 1);
}
// Construct a count array where value at every index
// contains count of smaller characters in whole string
void populateAndIncreaseCount(int* count, char* str)
{
int i;
for (i = 0; str[i]; ++i)
++count[str[i]];
for (i = 1; i < MAX_CHAR; ++i)
count[i] += count[i - 1];
}
// Removes a character ch from count[] array
// constructed by populateAndIncreaseCount()
void updatecount(int* count, char ch)
{
int i;
for (i = ch; i < MAX_CHAR; ++i)
--count[i];
}
// A function to find rank of a string in all permutations
// of characters
int findRank(char* str)
{
int len = strlen(str);
int mul = fact(len);
int rank = 1, i;
// all elements of count[] are initialized with 0
int count[MAX_CHAR] = { 0 };
// Populate the count array such that count[i]
// contains count of characters which are present
// in str and are smaller than i
populateAndIncreaseCount(count, str);
for (i = 0; i < len; ++i) {
mul /= len - i;
// count number of chars smaller than str[i]
// fron str[i+1] to str[len-1]
rank += count[str[i] - 1] * mul;
// Reduce count of characters greater than str[i]
updatecount(count, str[i]);
}
return rank;
}
// Driver program to test above function
int main()
{
char str[] = "string";
cout << findRank(str);
return 0;
}
// This is code is contributed by rathbhupendra
C
// A O(n) solution for finding rank of string
#include
#include
#define MAX_CHAR 256
// A utility function to find factorial of n
int fact(int n)
{
return (n <= 1) ? 1 : n * fact(n - 1);
}
// Construct a count array where value at every index
// contains count of smaller characters in whole string
void populateAndIncreaseCount(int* count, char* str)
{
int i;
for (i = 0; str[i]; ++i)
++count[str[i]];
for (i = 1; i < MAX_CHAR; ++i)
count[i] += count[i - 1];
}
// Removes a character ch from count[] array
// constructed by populateAndIncreaseCount()
void updatecount(int* count, char ch)
{
int i;
for (i = ch; i < MAX_CHAR; ++i)
--count[i];
}
// A function to find rank of a string in all permutations
// of characters
int findRank(char* str)
{
int len = strlen(str);
int mul = fact(len);
int rank = 1, i;
// all elements of count[] are initialized with 0
int count[MAX_CHAR] = { 0 };
// Populate the count array such that count[i]
// contains count of characters which are present
// in str and are smaller than i
populateAndIncreaseCount(count, str);
for (i = 0; i < len; ++i) {
mul /= len - i;
// count number of chars smaller than str[i]
// fron str[i+1] to str[len-1]
rank += count[str[i] - 1] * mul;
// Reduce count of characters greater than str[i]
updatecount(count, str[i]);
}
return rank;
}
// Driver program to test above function
int main()
{
char str[] = "string";
printf("%d", findRank(str));
return 0;
}
Java
// A O(n) solution for finding rank of string
class GFG {
static int MAX_CHAR = 256;
// A utility function to find factorial of n
static int fact(int n)
{
return (n <= 1) ? 1 : n * fact(n - 1);
}
// Construct a count array where value at every index
// contains count of smaller characters in whole string
static void populateAndIncreaseCount(int[] count, char[] str)
{
int i;
for (i = 0; i < str.length; ++i)
++count[str[i]];
for (i = 1; i < MAX_CHAR; ++i)
count[i] += count[i - 1];
}
// Removes a character ch from count[] array
// constructed by populateAndIncreaseCount()
static void updatecount(int[] count, char ch)
{
int i;
for (i = ch; i < MAX_CHAR; ++i)
--count[i];
}
// A function to find rank of a string in all permutations
// of characters
static int findRank(char[] str)
{
int len = str.length;
int mul = fact(len);
int rank = 1, i;
// all elements of count[] are initialized with 0
int count[] = new int[MAX_CHAR];
// Populate the count array such that count[i]
// contains count of characters which are present
// in str and are smaller than i
populateAndIncreaseCount(count, str);
for (i = 0; i < len; ++i) {
mul /= len - i;
// count number of chars smaller than str[i]
// fron str[i+1] to str[len-1]
rank += count[str[i] - 1] * mul;
// Reduce count of characters greater than str[i]
updatecount(count, str[i]);
}
return rank;
}
// Driver code
public static void main(String args[])
{
char str[] = "string".toCharArray();
System.out.println(findRank(str));
}
}
// This code has been contributed by 29AjayKumar
Python3
# A O(n) solution for finding rank of string
MAX_CHAR=256;
# all elements of count[] are initialized with 0
count=[0]*(MAX_CHAR + 1);
# A utility function to find factorial of n
def fact(n):
return 1 if(n <= 1) else (n * fact(n - 1));
# Construct a count array where value at every index
# contains count of smaller characters in whole string
def populateAndIncreaseCount(str):
for i in range(len(str)):
count[ord(str[i])]+=1;
for i in range(1,MAX_CHAR):
count[i] += count[i - 1];
# Removes a character ch from count[] array
# constructed by populateAndIncreaseCount()
def updatecount(ch):
for i in range(ord(ch),MAX_CHAR):
count[i]-=1;
# A function to find rank of a string in all permutations
# of characters
def findRank(str):
len1 = len(str);
mul = fact(len1);
rank = 1;
# Populate the count array such that count[i]
# contains count of characters which are present
# in str and are smaller than i
populateAndIncreaseCount(str);
for i in range(len1):
mul = mul//(len1 - i);
# count number of chars smaller than str[i]
# fron str[i+1] to str[len-1]
rank += count[ord(str[i]) - 1] * mul;
# Reduce count of characters greater than str[i]
updatecount(str[i]);
return rank;
# Driver code
str = "string";
print(findRank(str));
# This is code is contributed by chandan_jnu
C#
// A O(n) solution for finding rank of string
using System;
class GFG {
static int MAX_CHAR = 256;
// A utility function to find factorial of n
static int fact(int n)
{
return (n <= 1) ? 1 : n * fact(n - 1);
}
// Construct a count array where value at every index
// contains count of smaller characters in whole string
static void populateAndIncreaseCount(int[] count, char[] str)
{
int i;
for (i = 0; i < str.Length; ++i)
++count[str[i]];
for (i = 1; i < MAX_CHAR; ++i)
count[i] += count[i - 1];
}
// Removes a character ch from count[] array
// constructed by populateAndIncreaseCount()
static void updatecount(int[] count, char ch)
{
int i;
for (i = ch; i < MAX_CHAR; ++i)
--count[i];
}
// A function to find rank of a string in all permutations
// of characters
static int findRank(char[] str)
{
int len = str.Length;
int mul = fact(len);
int rank = 1, i;
// all elements of count[] are initialized with 0
int[] count = new int[MAX_CHAR];
// Populate the count array such that count[i]
// contains count of characters which are present
// in str and are smaller than i
populateAndIncreaseCount(count, str);
for (i = 0; i < len; ++i) {
mul /= len - i;
// count number of chars smaller than str[i]
// fron str[i+1] to str[len-1]
rank += count[str[i] - 1] * mul;
// Reduce count of characters greater than str[i]
updatecount(count, str[i]);
}
return rank;
}
// Driver code
public static void Main(String[] args)
{
char[] str = "string".ToCharArray();
Console.WriteLine(findRank(str));
}
}
/* This code contributed by PrinciRaj1992 */
PHP
输出:
598
上述解决方案的时间复杂度为O(n ^ 2)。通过创建大小为256的辅助数组,可以将时间复杂度降低到O(n)。请参见以下代码。
C++
// A O(n) solution for finding rank of string
#include
using namespace std;
#define MAX_CHAR 256
// A utility function to find factorial of n
int fact(int n)
{
return (n <= 1) ? 1 : n * fact(n - 1);
}
// Construct a count array where value at every index
// contains count of smaller characters in whole string
void populateAndIncreaseCount(int* count, char* str)
{
int i;
for (i = 0; str[i]; ++i)
++count[str[i]];
for (i = 1; i < MAX_CHAR; ++i)
count[i] += count[i - 1];
}
// Removes a character ch from count[] array
// constructed by populateAndIncreaseCount()
void updatecount(int* count, char ch)
{
int i;
for (i = ch; i < MAX_CHAR; ++i)
--count[i];
}
// A function to find rank of a string in all permutations
// of characters
int findRank(char* str)
{
int len = strlen(str);
int mul = fact(len);
int rank = 1, i;
// all elements of count[] are initialized with 0
int count[MAX_CHAR] = { 0 };
// Populate the count array such that count[i]
// contains count of characters which are present
// in str and are smaller than i
populateAndIncreaseCount(count, str);
for (i = 0; i < len; ++i) {
mul /= len - i;
// count number of chars smaller than str[i]
// fron str[i+1] to str[len-1]
rank += count[str[i] - 1] * mul;
// Reduce count of characters greater than str[i]
updatecount(count, str[i]);
}
return rank;
}
// Driver program to test above function
int main()
{
char str[] = "string";
cout << findRank(str);
return 0;
}
// This is code is contributed by rathbhupendra
C
// A O(n) solution for finding rank of string
#include
#include
#define MAX_CHAR 256
// A utility function to find factorial of n
int fact(int n)
{
return (n <= 1) ? 1 : n * fact(n - 1);
}
// Construct a count array where value at every index
// contains count of smaller characters in whole string
void populateAndIncreaseCount(int* count, char* str)
{
int i;
for (i = 0; str[i]; ++i)
++count[str[i]];
for (i = 1; i < MAX_CHAR; ++i)
count[i] += count[i - 1];
}
// Removes a character ch from count[] array
// constructed by populateAndIncreaseCount()
void updatecount(int* count, char ch)
{
int i;
for (i = ch; i < MAX_CHAR; ++i)
--count[i];
}
// A function to find rank of a string in all permutations
// of characters
int findRank(char* str)
{
int len = strlen(str);
int mul = fact(len);
int rank = 1, i;
// all elements of count[] are initialized with 0
int count[MAX_CHAR] = { 0 };
// Populate the count array such that count[i]
// contains count of characters which are present
// in str and are smaller than i
populateAndIncreaseCount(count, str);
for (i = 0; i < len; ++i) {
mul /= len - i;
// count number of chars smaller than str[i]
// fron str[i+1] to str[len-1]
rank += count[str[i] - 1] * mul;
// Reduce count of characters greater than str[i]
updatecount(count, str[i]);
}
return rank;
}
// Driver program to test above function
int main()
{
char str[] = "string";
printf("%d", findRank(str));
return 0;
}
Java
// A O(n) solution for finding rank of string
class GFG {
static int MAX_CHAR = 256;
// A utility function to find factorial of n
static int fact(int n)
{
return (n <= 1) ? 1 : n * fact(n - 1);
}
// Construct a count array where value at every index
// contains count of smaller characters in whole string
static void populateAndIncreaseCount(int[] count, char[] str)
{
int i;
for (i = 0; i < str.length; ++i)
++count[str[i]];
for (i = 1; i < MAX_CHAR; ++i)
count[i] += count[i - 1];
}
// Removes a character ch from count[] array
// constructed by populateAndIncreaseCount()
static void updatecount(int[] count, char ch)
{
int i;
for (i = ch; i < MAX_CHAR; ++i)
--count[i];
}
// A function to find rank of a string in all permutations
// of characters
static int findRank(char[] str)
{
int len = str.length;
int mul = fact(len);
int rank = 1, i;
// all elements of count[] are initialized with 0
int count[] = new int[MAX_CHAR];
// Populate the count array such that count[i]
// contains count of characters which are present
// in str and are smaller than i
populateAndIncreaseCount(count, str);
for (i = 0; i < len; ++i) {
mul /= len - i;
// count number of chars smaller than str[i]
// fron str[i+1] to str[len-1]
rank += count[str[i] - 1] * mul;
// Reduce count of characters greater than str[i]
updatecount(count, str[i]);
}
return rank;
}
// Driver code
public static void main(String args[])
{
char str[] = "string".toCharArray();
System.out.println(findRank(str));
}
}
// This code has been contributed by 29AjayKumar
Python3
# A O(n) solution for finding rank of string
MAX_CHAR=256;
# all elements of count[] are initialized with 0
count=[0]*(MAX_CHAR + 1);
# A utility function to find factorial of n
def fact(n):
return 1 if(n <= 1) else (n * fact(n - 1));
# Construct a count array where value at every index
# contains count of smaller characters in whole string
def populateAndIncreaseCount(str):
for i in range(len(str)):
count[ord(str[i])]+=1;
for i in range(1,MAX_CHAR):
count[i] += count[i - 1];
# Removes a character ch from count[] array
# constructed by populateAndIncreaseCount()
def updatecount(ch):
for i in range(ord(ch),MAX_CHAR):
count[i]-=1;
# A function to find rank of a string in all permutations
# of characters
def findRank(str):
len1 = len(str);
mul = fact(len1);
rank = 1;
# Populate the count array such that count[i]
# contains count of characters which are present
# in str and are smaller than i
populateAndIncreaseCount(str);
for i in range(len1):
mul = mul//(len1 - i);
# count number of chars smaller than str[i]
# fron str[i+1] to str[len-1]
rank += count[ord(str[i]) - 1] * mul;
# Reduce count of characters greater than str[i]
updatecount(str[i]);
return rank;
# Driver code
str = "string";
print(findRank(str));
# This is code is contributed by chandan_jnu
C#
// A O(n) solution for finding rank of string
using System;
class GFG {
static int MAX_CHAR = 256;
// A utility function to find factorial of n
static int fact(int n)
{
return (n <= 1) ? 1 : n * fact(n - 1);
}
// Construct a count array where value at every index
// contains count of smaller characters in whole string
static void populateAndIncreaseCount(int[] count, char[] str)
{
int i;
for (i = 0; i < str.Length; ++i)
++count[str[i]];
for (i = 1; i < MAX_CHAR; ++i)
count[i] += count[i - 1];
}
// Removes a character ch from count[] array
// constructed by populateAndIncreaseCount()
static void updatecount(int[] count, char ch)
{
int i;
for (i = ch; i < MAX_CHAR; ++i)
--count[i];
}
// A function to find rank of a string in all permutations
// of characters
static int findRank(char[] str)
{
int len = str.Length;
int mul = fact(len);
int rank = 1, i;
// all elements of count[] are initialized with 0
int[] count = new int[MAX_CHAR];
// Populate the count array such that count[i]
// contains count of characters which are present
// in str and are smaller than i
populateAndIncreaseCount(count, str);
for (i = 0; i < len; ++i) {
mul /= len - i;
// count number of chars smaller than str[i]
// fron str[i+1] to str[len-1]
rank += count[str[i] - 1] * mul;
// Reduce count of characters greater than str[i]
updatecount(count, str[i]);
}
return rank;
}
// Driver code
public static void Main(String[] args)
{
char[] str = "string".ToCharArray();
Console.WriteLine(findRank(str));
}
}
/* This code contributed by PrinciRaj1992 */
的PHP
输出:
598