Given a string str, its sub-strings are formed in such a way that all the sub-strings starting with the first character of the string will occur first in the sorted order of their lengths followed by all the sub-strings starting with the second character of the string in the sorted order of their lengths and so on.
For example for the string abc, its sub-strings in the required order are a, ab, abc, b, bc and c.
Now given an integer k, the task is to find the kth sub-string in the required order.
Examples:
Input: str = abc, k = 4
Output: b
The required order is “a”, “ab”, “abc”, “b”, “bc” and “c”
Input: str = abc, k = 9
Output: -1
Only 6 sub-strings are possible.
Approach: The idea is to use binary search. An array substring will be used to store the number of sub-strings starting with ith character + substring[i – 1]. Now using binary search on the array substring, find the starting index of the required sub-string and then find the ending index for the same sub-string with end = length_of_string – (substring[start] – k).
Below is the implementation of the above approach:
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std;
// Function to prints kth sub-string void Printksubstring(string str, int n, int k)
{ // Total sub-strings possible
int total = (n * (n + 1)) / 2;
// If k is greater than total
// number of sub-strings
if (k > total) {
printf ( "-1\n" );
return ;
}
// To store number of sub-strings starting
// with ith character of the string
int substring[n + 1];
substring[0] = 0;
// Compute the values
int temp = n;
for ( int i = 1; i <= n; i++) {
// substring[i - 1] is added
// to store the cumulative sum
substring[i] = substring[i - 1] + temp;
temp--;
}
// Binary search to find the starting index
// of the kth sub-string
int l = 1;
int h = n;
int start = 0;
while (l <= h) {
int m = (l + h) / 2;
if (substring[m] > k) {
start = m;
h = m - 1;
}
else if (substring[m] < k)
l = m + 1;
else {
start = m;
break ;
}
}
// To store the ending index of
// the kth sub-string
int end = n - (substring[start] - k);
// Print the sub-string
for ( int i = start - 1; i < end; i++)
cout << str[i];
} // Driver code int main()
{ string str = "abc" ;
int k = 4;
int n = str.length();
Printksubstring(str, n, k);
return 0;
} |
// Java implementation of the approach class GFG
{ // Function to prints kth sub-string
static void Printksubstring(String str, int n, int k)
{
// Total sub-strings possible
int total = (n * (n + 1 )) / 2 ;
// If k is greater than total
// number of sub-strings
if (k > total)
{
System.out.printf( "-1\n" );
return ;
}
// To store number of sub-strings starting
// with ith character of the string
int substring[] = new int [n + 1 ];
substring[ 0 ] = 0 ;
// Compute the values
int temp = n;
for ( int i = 1 ; i <= n; i++)
{
// substring[i - 1] is added
// to store the cumulative sum
substring[i] = substring[i - 1 ] + temp;
temp--;
}
// Binary search to find the starting index
// of the kth sub-string
int l = 1 ;
int h = n;
int start = 0 ;
while (l <= h)
{
int m = (l + h) / 2 ;
if (substring[m] > k)
{
start = m;
h = m - 1 ;
}
else if (substring[m] < k)
{
l = m + 1 ;
}
else
{
start = m;
break ;
}
}
// To store the ending index of
// the kth sub-string
int end = n - (substring[start] - k);
// Print the sub-string
for ( int i = start - 1 ; i < end; i++)
{
System.out.print(str.charAt(i));
}
}
// Driver code
public static void main(String[] args)
{
String str = "abc" ;
int k = 4 ;
int n = str.length();
Printksubstring(str, n, k);
}
} // This code has been contributed by 29AjayKumar |
# Python3 implementation of the approach # Function to prints kth sub-string def Printksubstring(str1, n, k):
# Total sub-strings possible
total = int ((n * (n + 1 )) / 2 )
# If k is greater than total
# number of sub-strings
if (k > total):
print ( "-1" )
return
# To store number of sub-strings starting
# with ith character of the string
substring = [ 0 for i in range (n + 1 )]
substring[ 0 ] = 0
# Compute the values
temp = n
for i in range ( 1 , n + 1 , 1 ):
# substring[i - 1] is added
# to store the cumulative sum
substring[i] = substring[i - 1 ] + temp
temp - = 1
# Binary search to find the starting index
# of the kth sub-string
l = 1
h = n
start = 0
while (l < = h):
m = int ((l + h) / 2 )
if (substring[m] > k):
start = m
h = m - 1
elif (substring[m] < k):
l = m + 1
else :
start = m
break
# To store the ending index of
# the kth sub-string
end = n - (substring[start] - k)
# Print the sub-string
for i in range (start - 1 , end):
print (str1[i], end = "")
# Driver code if __name__ = = '__main__' :
str1 = "abc"
k = 4
n = len (str1)
Printksubstring(str1, n, k)
# This code is contributed by # Surendra_Gangwar |
// C# implementation of the approach using System;
class GFG
{ // Function to prints kth sub-string
static void Printksubstring(String str, int n, int k)
{
// Total sub-strings possible
int total = (n * (n + 1)) / 2;
// If k is greater than total
// number of sub-strings
if (k > total)
{
Console.Write( "-1\n" );
return ;
}
// To store number of sub-strings starting
// with ith character of the string
int []substring = new int [n + 1];
substring[0] = 0;
// Compute the values
int temp = n;
for ( int i = 1; i <= n; i++)
{
// substring[i - 1] is added
// to store the cumulative sum
substring[i] = substring[i - 1] + temp;
temp--;
}
// Binary search to find the starting index
// of the kth sub-string
int l = 1;
int h = n;
int start = 0;
while (l <= h)
{
int m = (l + h) / 2;
if (substring[m] > k)
{
start = m;
h = m - 1;
}
else if (substring[m] < k)
{
l = m + 1;
}
else
{
start = m;
break ;
}
}
// To store the ending index of
// the kth sub-string
int end = n - (substring[start] - k);
// Print the sub-string
for ( int i = start - 1; i < end; i++)
{
Console.Write(str[i]);
}
}
// Driver code
public static void Main(String[] args)
{
String str = "abc" ;
int k = 4;
int n = str.Length;
Printksubstring(str, n, k);
}
} // This code contributed by Rajput-Ji |
<?php // PHP implementation of the approach // Function to prints kth sub-string function Printksubstring( $str , $n , $k )
{ // Total sub-strings possible
$total = floor (( $n * ( $n + 1)) / 2);
// If k is greater than total
// number of sub-strings
if ( $k > $total )
{
printf( "-1\n" );
return ;
}
// To store number of sub-strings starting
// with ith character of the string
$substring = array ();
$substring [0] = 0;
// Compute the values
$temp = $n ;
for ( $i = 1; $i <= $n ; $i ++)
{
// substring[i - 1] is added
// to store the cumulative sum
$substring [ $i ] = $substring [ $i - 1] + $temp ;
$temp --;
}
// Binary search to find the starting index
// of the kth sub-string
$l = 1;
$h = $n ;
$start = 0;
while ( $l <= $h )
{
$m = floor (( $l + $h ) / 2);
if ( $substring [ $m ] > $k )
{
$start = $m ;
$h = $m - 1;
}
else if ( $substring [ $m ] < $k )
$l = $m + 1;
else
{
$start = $m ;
break ;
}
}
// To store the ending index of
// the kth sub-string
$end = $n - ( $substring [ $start ] - $k );
// Print the sub-string
for ( $i = $start - 1; $i < $end ; $i ++)
print ( $str [ $i ]);
} // Driver code $str = "abc" ;
$k = 4;
$n = strlen ( $str );
Printksubstring( $str , $n , $k );
// This code is contributed by Ryuga ?> |
<script> // Javascript implementation of the approach
// Function to prints kth sub-string
function Printksubstring(str, n, k)
{
// Total sub-strings possible
let total = parseInt((n * (n + 1)) / 2, 10);
// If k is greater than total
// number of sub-strings
if (k > total)
{
document.write( "-1" + "</br>" );
return ;
}
// To store number of sub-strings starting
// with ith character of the string
let substring = new Array(n + 1);
substring[0] = 0;
// Compute the values
let temp = n;
for (let i = 1; i <= n; i++)
{
// substring[i - 1] is added
// to store the cumulative sum
substring[i] = substring[i - 1] + temp;
temp--;
}
// Binary search to find the starting index
// of the kth sub-string
let l = 1;
let h = n;
let start = 0;
while (l <= h)
{
let m = parseInt((l + h) / 2, 10);
if (substring[m] > k)
{
start = m;
h = m - 1;
}
else if (substring[m] < k)
{
l = m + 1;
}
else
{
start = m;
break ;
}
}
// To store the ending index of
// the kth sub-string
let end = n - (substring[start] - k);
// Print the sub-string
for (let i = start - 1; i < end; i++)
{
document.write(str[i]);
}
}
let str = "abc" ;
let k = 4;
let n = str.length;
Printksubstring(str, n, k);
//This code is contributed by divyeshrabadiya07. </script> |
b
Time Complexity: O(N)
Auxiliary Space: O(N)