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: 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++
// 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
// 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
<?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 ?> |
Javascript
<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)
Please Login to comment...