Given a string and an integer k, find the kth sub-string when all the sub-strings are sorted according to the given condition
Last Updated :
05 Aug, 2021
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++
#include <bits/stdc++.h>
using namespace std;
void Printksubstring(string str, int n, int k)
{
int total = (n * (n + 1)) / 2;
if (k > total) {
printf ( "-1\n" );
return ;
}
int substring[n + 1];
substring[0] = 0;
int temp = n;
for ( int i = 1; i <= n; i++) {
substring[i] = substring[i - 1] + temp;
temp--;
}
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 ;
}
}
int end = n - (substring[start] - k);
for ( int i = start - 1; i < end; i++)
cout << str[i];
}
int main()
{
string str = "abc" ;
int k = 4;
int n = str.length();
Printksubstring(str, n, k);
return 0;
}
|
Java
class GFG
{
static void Printksubstring(String str, int n, int k)
{
int total = (n * (n + 1 )) / 2 ;
if (k > total)
{
System.out.printf( "-1\n" );
return ;
}
int substring[] = new int [n + 1 ];
substring[ 0 ] = 0 ;
int temp = n;
for ( int i = 1 ; i <= n; i++)
{
substring[i] = substring[i - 1 ] + temp;
temp--;
}
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 ;
}
}
int end = n - (substring[start] - k);
for ( int i = start - 1 ; i < end; i++)
{
System.out.print(str.charAt(i));
}
}
public static void main(String[] args)
{
String str = "abc" ;
int k = 4 ;
int n = str.length();
Printksubstring(str, n, k);
}
}
|
Python3
def Printksubstring(str1, n, k):
total = int ((n * (n + 1 )) / 2 )
if (k > total):
print ( "-1" )
return
substring = [ 0 for i in range (n + 1 )]
substring[ 0 ] = 0
temp = n
for i in range ( 1 , n + 1 , 1 ):
substring[i] = substring[i - 1 ] + temp
temp - = 1
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
end = n - (substring[start] - k)
for i in range (start - 1 , end):
print (str1[i], end = "")
if __name__ = = '__main__' :
str1 = "abc"
k = 4
n = len (str1)
Printksubstring(str1, n, k)
|
C#
using System;
class GFG
{
static void Printksubstring(String str, int n, int k)
{
int total = (n * (n + 1)) / 2;
if (k > total)
{
Console.Write( "-1\n" );
return ;
}
int []substring = new int [n + 1];
substring[0] = 0;
int temp = n;
for ( int i = 1; i <= n; i++)
{
substring[i] = substring[i - 1] + temp;
temp--;
}
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 ;
}
}
int end = n - (substring[start] - k);
for ( int i = start - 1; i < end; i++)
{
Console.Write(str[i]);
}
}
public static void Main(String[] args)
{
String str = "abc" ;
int k = 4;
int n = str.Length;
Printksubstring(str, n, k);
}
}
|
PHP
<?php
function Printksubstring( $str , $n , $k )
{
$total = floor (( $n * ( $n + 1)) / 2);
if ( $k > $total )
{
printf( "-1\n" );
return ;
}
$substring = array ();
$substring [0] = 0;
$temp = $n ;
for ( $i = 1; $i <= $n ; $i ++)
{
$substring [ $i ] = $substring [ $i - 1] + $temp ;
$temp --;
}
$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 ;
}
}
$end = $n - ( $substring [ $start ] - $k );
for ( $i = $start - 1; $i < $end ; $i ++)
print ( $str [ $i ]);
}
$str = "abc" ;
$k = 4;
$n = strlen ( $str );
Printksubstring( $str , $n , $k );
?>
|
Javascript
<script>
function Printksubstring(str, n, k)
{
let total = parseInt((n * (n + 1)) / 2, 10);
if (k > total)
{
document.write( "-1" + "</br>" );
return ;
}
let substring = new Array(n + 1);
substring[0] = 0;
let temp = n;
for (let i = 1; i <= n; i++)
{
substring[i] = substring[i - 1] + temp;
temp--;
}
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 ;
}
}
let end = n - (substring[start] - k);
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);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...