GeeksforGeeks App
Open App
Browser
Continue

# Given a string and an integer k, find the kth sub-string when all the sub-strings are sorted according to the given condition

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:
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++

 `// C++ implementation of the approach``#include ``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

 `// 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

 `# 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#

 `// 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

 ` ``\$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``?>`

## Javascript

 ``

Output:

`b`

Time Complexity: O(N)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up