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:
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
Related Articles