Lexicographic rank of a Binary String
Last Updated :
29 Jan, 2022
Given a binary string S of length N, the task is to find the lexicographic rank of the given string.
Examples:
Input: S = “001”
Output: 8
Explanation:
Strings in order of their increasing rank:
“0” = 1,
“1” = 2,
“00” = 3,
“01” = 4,
“10” = 5,
“11” = 6,
“000” = 7,
“001” = 8.
Input: S = “01”
Output: 4
Naive Approach: The simplest approach is to generate all possible binary strings (consisting of 0s and 1s) up to length N and store them in an array. Once done, sort the array of strings in lexicographic order and print the index of the given string in the array.
Time Complexity: O(2N)
Auxiliary Space: O(1)
Efficient Approach: The idea is to generate a binary string consisting of 0s and 1s by replacing every occurrence of ‘a’ with 0 and ‘b’ with 1. Therefore, the strings in the list become:
“a” = 0,
“b” = 1,
“aa” = 00,
“ab” = 01,
“ba” = 10,
“bb” = 11,
“aaa” = 000,
“aab” = 001 and so on.
It can be observed that for a string of size N, there exist (2N – 2) strings of length less than N before that given string. Let it be equal to X. Now, its lexicographic position among strings of length N can be calculated by converting the string into its decimal equivalent number and adding 1 to it. Let it be equal to Y.
Rank of a string = X + Y + 1
= (2N – 2) + Y + 1
= 2N + Y – 1
Below is the implementation of the above approach:
C++
#include <iostream>
using namespace std;
void findRank(string s)
{
int N = s.size();
string bin;
for ( int i = 0; i < N; i++)
{
if (s[i] == '0' )
bin += "0" ;
else
bin += "1" ;
}
long long X = 1ll<<N;
long long res = 0, val = 1;
for ( int i = N - 1; i >= 0; i--)
{
if (bin[i] == '1' )
res += (val);
val *= 2ll;
}
long long Y = res;
long ans = X + Y - 1;
cout << ans;
}
int main()
{
string S = "001" ;
findRank(S);
return 0;
}
|
Java
import java.io.*;
import java.lang.*;
import java.util.*;
public class Main {
static void findRank(String s)
{
int N = s.length();
StringBuilder sb = new StringBuilder( "" );
for ( int i = 0 ; i < N; i++) {
if (s.charAt(i) == '0' )
sb.append( '0' );
else
sb.append( '1' );
}
String bin = sb.toString();
long X = ( long )Math.pow( 2 , N);
long Y = Long.parseLong(bin, 2 );
long ans = X + Y - 1 ;
System.out.println(ans);
}
public static void main(String[] args)
{
String S = "001" ;
findRank(S);
}
}
|
Python3
def findRank(s):
N = len (s);
sb = "";
for i in range ( 0 ,N):
if (s[i] = = '0' ):
sb + = str ( '0' );
else :
sb + = str ( '1' );
bin = str (sb);
X = pow ( 2 , N);
Y = int ( bin );
ans = X + Y - 1 ;
print (ans);
if __name__ = = '__main__' :
S = "001" ;
findRank(S);
|
C#
using System;
class GFG
{
static void findRank( string s)
{
int N = s.Length;
string bin = "" ;
for ( int i = 0; i < N; i++)
{
if (s[i] == '0' )
bin += "0" ;
else
bin += "1" ;
}
int X = 1<<N;
int res = 0, val = 1;
for ( int i = N - 1; i >= 0; i--)
{
if (bin[i] == '1' )
res += (val);
val *= 2;
}
int Y = res;
int ans = X + Y - 1;
Console.Write(ans);
}
public static void Main()
{
string S = "001" ;
findRank(S);
}
}
|
Javascript
<script>
function findRank( s)
{
var N = s.length;
var bin = "" ;
for ( var i = 0; i < N; i++)
{
if (s[i] == '0' )
bin += "0" ;
else
bin += "1" ;
}
var X = 1<<N;
var res = 0, val = 1;
for ( var i = N - 1; i >= 0; i--)
{
if (bin[i] == '1' )
res += (val);
val *= 2;
}
var Y = res;
var ans = X + Y - 1;
document.write( ans);
}
var S = "001" ;
findRank(S);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...