Find the n-th binary string in sorted order
Given a positive integer n, the task is to find the nth string in the following infinite list of all possible strings over two symbols a and b sorted lexicographically (Dictionary).
a, b, aa, ab, ba, bb, aaa, aab, aba, abb, baa, bab, bba, bbb, aaaa, …
Examples:
Input: n = 6
Output: bb
Input: n = 11
Output: baa
A simple approach is to generate all strings up to n and then determine the nth string. However, the approach is not suitable for large values of n.
An efficient approach is based on the fact that the number of length k strings that can be generated using 2 symbols is 2k. Based on this we can calculate the relative index from the actual index(n) with respect to the length of the string in the list. The string at nth index can then be determined easily using binary form of the relative index as the list is sorted. The following formula is used for calculation,
relative index = n + 1 – 2floor(log(n + 1))
Consider the following example:
Let n = 11 then floor(log(n + 1)) = 3.
This suggests that index n consists of a length 3 string and length 3 strings start from (23 – 1) = 7th index and 7th index contains the string “aaa”.
Therefore, relative index = 11 + 1 – 23 = 4.
This is the index relative to 7. Now, the string at index n = 11 can be simply obtained from the binary interpretation of the relative index 4.
Here 0 means a and 1 means b. The table below illustrates this:
0 |
000 |
aaa |
1 |
001 |
aab |
2 |
010 |
aba |
3 |
011 |
abb |
4 |
100 |
baa |
5 |
101 |
bab |
6 |
110 |
bba |
7 |
111 |
bbb |
Hence the string present at 11th index (relative index 4) is “baa”
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define ll long long int
string obtain_str(ll n)
{
ll len = ( int )log2(n + 1);
ll rel_ind = n + 1 - pow (2, len);
ll i = 0;
string str = "" ;
for (i = 0; i < len; i++) {
str += 'a' ;
}
i = 0;
while (rel_ind > 0) {
if (rel_ind % 2 == 1)
str[i] = 'b' ;
rel_ind /= 2;
i++;
}
reverse(str.begin(), str.end());
return str;
}
int main()
{
ll n = 11;
cout << obtain_str(n);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class Gfg {
static String obtain_str( int n)
{
int len = ( int )Math.floor((Math.log(n + 1 ) / Math.log( 2 )));
int rel_ind = n + 1 - ( int )Math.pow( 2 , len);
int i = 0 ;
StringBuilder str = new StringBuilder();
for (i = 0 ; i < len; i++) {
str.append( 'a' );
}
i = 0 ;
while (rel_ind > 0 ) {
if (rel_ind % 2 == 1 )
str.setCharAt(i, 'b' );
rel_ind /= 2 ;
i++;
}
str = str.reverse();
return str.toString();
}
public static void main(String args[])
{
int n = 11 ;
System.out.print(obtain_str(n));
}
}
|
Python3
from math import log2
def obtain_str(n) :
length = int (log2(n + 1 ))
rel_ind = n + 1 - pow ( 2 , length)
i = 0
string = ""
for i in range (length) :
string + = 'a'
i = 0
string_list = list (string)
while (rel_ind > 0 ) :
if (rel_ind % 2 = = 1 ) :
string_list[i] = 'b'
rel_ind / / = 2
i + = 1
string_list.reverse()
string = "".join(string_list)
return string
if __name__ = = "__main__" :
n = 11
print (obtain_str(n))
|
C#
using System;
using System.Text;
class GFG
{
static String obtain_str( int n)
{
int len = ( int )Math.Floor((Math.Log(n + 1) /
Math.Log(2)));
int rel_ind = n + 1 - ( int )Math.Pow(2, len);
int i = 0;
StringBuilder str = new StringBuilder();
for (i = 0; i < len; i++)
{
str.Append( 'a' );
}
i = 0;
while (rel_ind > 0)
{
if (rel_ind % 2 == 1)
str[i]= 'b' ;
rel_ind /= 2;
i++;
}
return reverse(str.ToString());
}
static String reverse(String input)
{
char [] a = input.ToCharArray();
int l, r = a.Length - 1;
for (l = 0; l < r; l++, r--)
{
char temp = a[l];
a[l] = a[r];
a[r] = temp;
}
return String.Join( "" , a);
}
public static void Main(String []args)
{
int n = 11;
Console.Write(obtain_str(n));
}
}
|
Javascript
<script>
function obtain_str(n)
{
let len = Math.floor((Math.log(n + 1) /
Math.log(2)));
let rel_ind = n + 1 - Math.pow(2, len);
let i = 0;
let str = [];
for (i = 0; i < len; i++)
{
str.push('a ');
}
i = 0;
// Convert relative index to Binary
// form and set 0 = a and 1 = b
while (rel_ind > 0)
{
if (rel_ind % 2 == 1)
str[i]=' b ';
rel_ind = parseInt(rel_ind / 2, 10);
i++;
}
// Reverse and return the string
return reverse(str.join(""));
}
function reverse(input)
{
let a = input.split(' ');
let l, r = a.length - 1;
for (l = 0; l < r; l++, r--)
{
let temp = a[l];
a[l] = a[r];
a[r] = temp;
}
return a.join( "" );
}
let n = 11;
document.write(obtain_str(n));
</script>
|
PHP
<?php
function obtain_str( $n )
{
$len = (int)(log( $n + 1) / log(2));
$rel_ind = $n + 1 - pow(2, $len );
$i = 0;
$str = "" ;
for ( $i = 0; $i < $len ; $i ++)
{
$str .= 'a' ;
}
$i = 0;
while ( $rel_ind > 0)
{
if ( $rel_ind % 2 == 1)
$str [ $i ] = 'b' ;
$rel_ind = (int)( $rel_ind / 2);
$i ++;
}
return strrev ( $str );
}
$n = 11;
echo obtain_str( $n );
?>
|
Time complexity : O(logn)
Auxiliary Space: O(1)
Last Updated :
01 Nov, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...