Open In App

Kth non-overlapping Substring of length M after sorting given String lexicographically

Last Updated : 23 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given string str of size N and two integers M and K (N is divisible by M), the task is to find the Kth non-overlapping substring of size M after sorting the given string lexicographically

Examples:

Input: str = “hwnriw”, M = 3, K = 1
Output: hin
Explanation: Non overlapping substrings of size 3 after sorting are “hin” “rww”. 
So 1st string is “hin” .

Input: str = “xeabcks”, M = 3, K = 1
Output: abc

 

Naive Approach: The basic idea to solve the problem is to Sort the entire string and after that find the Kth non-overlapping substring which starts from the index (K-1)*M.

Follow the below steps to solve the problem:

  • Sort the entire string. 
  • Get the starting index of the Kth substring as mentioned below.
  • And after that take the substring of size M from that index.

Below is the implementation of the above approach:

C++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to get the kth substring
string getKthString(int N, int M, int K,
                    string str)
{
    // Sort the entire string
    sort(str.begin(), str.end());
 
    // Get the starting index of the kth
    // lexicographically string
    int startingIndex = (K - 1) * M;
 
    string kthString = "";
 
    // To track the size of string
    int size = 0;
 
    // Run a loop till size is not equal to M
    for (int i = startingIndex;
         i < N && size < M; i++) {
 
        // Add the current character to the
        // resulting string
        kthString += str[i];
 
        // Increase the size by 1
        size++;
    }
 
    // Return the  resultant string
    return kthString;
}
 
// Driver Function
int main()
{
    int N = 6;
    int M = 3;
    int K = 1;
    string str = "xeabcks";
 
    // Function call
    cout << getKthString(N, M, K, str);
 
    return 0;
}


Java




// Java code to implement the approach
import java.io.*;
import java.util.*;
 
class GFG
{
 
  // Function to get the kth substring
  public static String getKthString(int N, int M, int K,
                                    String str)
  {
 
    // Sort the entire string
    char tempArray[] = str.toCharArray();
    Arrays.sort(tempArray);
    str = new String(tempArray);
 
    // Get the starting index of the kth
    // lexicographically string
    int startingIndex = (K - 1) * M;
 
    String kthString = "";
 
    // To track the size of string
    int size = 0;
 
    // Run a loop till size is not equal to M
    for (int i = startingIndex; i < N && size < M;
         i++) {
 
      // Add the current character to the
      // resulting string
      kthString += str.charAt(i);
 
      // Increase the size by 1
      size++;
    }
 
    // Return the  resultant string
    return kthString;
  }
 
  public static void main(String[] args)
  {
    int N = 6;
    int M = 3;
    int K = 1;
    String str = "xeabcks";
 
    // Function call
    System.out.print(getKthString(N, M, K, str));
  }
}
 
// This code is contributed by Rohit Pradhan


Python3




# Python3 code to implement the approach
 
# Function to get the kth substring
def getKthString(N, M, K, str):
     
    # Sort the entire string
    # We do this by converting the string to a list,
    # then sorting the list
    # then joining the list back
    # into a string
    str = "".join(sorted(list(str)))
     
    # Get the starting index of the kth
    # lexicographically string
    startingIndex=  (K - 1) * M
     
    kthString = ""
     
    # To track the size of string
    size = 0
    i = startingIndex
     
    # Run a loop till size is not equal to M
    while (i < N and size < M):
         
        # Add the current character to the
        # resulting string
        kthString += str[i]
         
        # Increase the size by 1
        size += 1
        i += 1
     
    # Return the  resultant string
    return kthString
 
# Driver Function
N = 6
M = 3
K = 1
str = "xeabcks"
 
# Function Call
print(getKthString(N, M, K, str))
 
# This code is contributed by phasing17.


C#




// C# code to implement the approach
using System;
class GFG {
 
    // Function to get the kth substring
    static String getKthString(int N, int M, int K,
                               string str)
    {
 
        // Sort the entire string
        char[] tempArray = new char[str.Length];
        for (int i = 0; i < str.Length; i++) {
            tempArray[i] = str[i];
        }
        Array.Sort(tempArray);
        str = new string(tempArray);
 
        // Get the starting index of the kth
        // lexicographically string
        int startingIndex = (K - 1) * M;
 
        string kthString = "";
 
        // To track the size of string
        int size = 0;
 
        // Run a loop till size is not equal to M
        for (int i = startingIndex; i < N && size < M;
             i++) {
 
            // Add the current character to the
            // resulting string
            kthString += str[i];
 
            // Increase the size by 1
            size++;
        }
 
        // Return the  resultant string
        return kthString;
    }
 
    public static int Main()
    {
        int N = 6;
        int M = 3;
        int K = 1;
        string str = "xeabcks";
 
        // Function call
        Console.Write(getKthString(N, M, K, str));
        return 0;
    }
}
 
// This code is contributed by Taranpreet


Javascript




<script>
 
  // Function to get the kth substring
  function getKthstring(N, M, K, str)
  {
   
    str = [...str];
 
    // Sort the entire string
     str.sort();
 
    // Get the starting index of the kth
    // lexicographically string
    int startingIndex = (K - 1) * M;
 
    int kthstring = "";
 
    // To track the size of string
    int size = 0;
 
    // Run a loop till size is not equal to M
    for (int i = startingIndex; i < N && size < M;
         i++) {
 
      // Add the current character to the
      // resulting string
      kthstring += str[i];
 
      // Increase the size by 1
      size++;
    }
 
    // Return the  resultant string
    return kthstring;
  }
 
    // Driver code
    let N = 6;
    let M = 3;
    let K = 1;
    let str = "xeabcks";
 
    // Function call
    document.write(getKthstring(N, M, K, str));
     
    // This code is contributed by sanjoy_62.
</script>


Output

abc

Time Complexity: O(N * Log N)
Auxiliary Space: O(1)

Efficient Approach: The problem can be solved efficiently using hashing and prefix sum based on the following idea:

There are total (K-1)*M characters before the starting character of the Kth substring. 
So store the frequency of all the characters. Then iterate from the smallest character present in the string and with the help of prefix sum find the first character of the Kth substring.

This will help solve the problem in linear time complexity.

C++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to get the kth substring
string getKthString(int N, int M, int K, string str)
{
    int a[26] = { 0 };
 
    // Storing the frequency of all the characters
    for (int i = 0; i < N; i++) {
        a[str[i] - 'a']++;
    }
 
    // Prefix array
    int prefix[26];
    prefix[0] = a[0];
    for (int i = 1; i < 26; i++) {
        prefix[i] = prefix[i - 1] + a[i];
    }
 
    // Get the starting index of the kth
    // lexicographically string
    int startingIndex = (K - 1) * M;
    int var = 0;
 
    // To track the size of string
    int size = 0;
 
    string kthString = "";
 
    for (int i = 0; i < 26; i++) {
        // Prefix array is smaller than
        // startingIndex or element is not present
        if (prefix[i] < startingIndex || a[i] == 0) {
            continue;
        }
        // This case is when prefix array
        // exceeds the startingIndex for
        // the first time
        else if (var == 0) {
            var = prefix[i] - startingIndex;
            for (int j = 0; j < var; j++) {
                kthString += char(97 + i);
                size++;
                if (size == M)
                    break;
            }
        }
        // Prefix array exceeding startingIndex
        // other than first time
        else {
            for (int j = 0; j < prefix[i] - prefix[i - 1];
                 j++) {
                kthString += char(97 + i);
                size++;
                if (size == M)
                    break;
            }
        }
        // Breaking from the loop if we
        // get the string of M size
        if (size == M)
            break;
    }
 
    // Return the resultant string
    return kthString;
}
 
// Driver Function
int main()
{
    int N = 6;
    int M = 3;
    int K = 1;
    string str = "xeabck";
 
    // Function call
    cout << getKthString(N, M, K, str);
 
    return 0;
}
 
// This code is contributed by Pushpesh Raj


Java




/*package whatever //do not write package name here */
 
import java.io.*;
 
class GFG {
    public static String getKthString(int N, int M, int K,
                                      String str)
    {
        int[] a = new int[26];
        // Storing the frequency of all the characters
        for (int i = 0; i < N; i++) {
            a[str.charAt(i) - 'a']++;
        }
 
        // Prefix array
        int[] prefix = new int[26];
        prefix[0] = a[0];
        for (int i = 1; i < 26; i++) {
            prefix[i] = prefix[i - 1] + a[i];
        }
 
        // Get the starting index of the kth
        // lexicographically string
        int startingIndex = (K - 1) * M;
        int var = 0;
 
        // To track the size of string
        int size = 0;
 
        String kthString = "";
 
        for (int i = 0; i < 26; i++) {
            // Prefix array is smaller than
            // startingIndex or element is not present
            if (prefix[i] < startingIndex || a[i] == 0) {
                continue;
            }
            // This case is when prefix array
            // exceeds the startingIndex for
            // the first time
            else if (var == 0) {
                var = prefix[i] - startingIndex;
                for (int j = 0; j < var; j++) {
                    kthString += (char)(97 + i);
                    size++;
                    if (size == M)
                        break;
                }
            }
            // Prefix array exceeding startingIndex
            // other than first time
            else {
                for (int j = 0;
                     j < prefix[i] - prefix[i - 1]; j++) {
                    kthString += (char)(97 + i);
                    size++;
                    if (size == M)
                        break;
                }
            }
            // Breaking from the loop if we
            // get the string of M size
            if (size == M)
                break;
        }
 
        // Return the resultant string
        return kthString;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int N = 6;
        int M = 3;
        int K = 1;
        String str = "xeabck";
        // Function call
        System.out.println(getKthString(N, M, K, str));
    }
}
//This code is contributed by KaaL-EL


Python3




# Python program for the above approach:
 
## Function to get the kth substring
def getKthString(N, M, K, str):
 
    a = [0]*26
 
    ## Storing the frequency of all the characters
    for i in range(N):
        a[ord(str[i]) - ord('a')]+=1
 
    ## Prefix array
    prefix = [0]*26
    prefix[0] = a[0]
    for i in range(1, 26):
        prefix[i] = prefix[i - 1] + a[i]
 
    ## Get the starting index of the kth
    ## lexicographically string
    startingIndex = (K - 1) * M
    var = 0
 
    ## To track the size of string
    size = 0
 
    kthString = ""
 
    for i in range(26):
 
        ## Prefix array is smaller than
        ## startingIndex or element is not present
        if (prefix[i] < startingIndex or a[i] == 0):
            continue
        ## This case is when prefix array
        ## exceeds the startingIndex for
        ## the first time
        elif (var == 0):
            var = prefix[i] - startingIndex;
            for j in range(var):
                kthString += chr(97 + i)
                size+=1
                if (size == M):
                    break
        ## Prefix array exceeding startingIndex
        ## other than first time
        else:
            for j in range(prefix[i] - prefix[i - 1]):
                kthString += chr(97 + i);
                size += 1
                if (size == M):
                    break
        ## Breaking from the loop if we
        ## get the string of M size
        if (size == M):
            break
 
    ## Return the resultant string
    return kthString
 
## Driver code
if __name__ == '__main__':
    N = 6;
    M = 3
    K = 1
    string = "xeabck"
 
    ## Function call
    print(getKthString(N, M, K, string))
     
    # This code is contributed by entertain2022.


C#




// C# program to implement above approach
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG
{
 
  public static String getKthString(int N, int M, int K,
                                    String str)
  {
    int[] a = new int[26];
     
    // Storing the frequency of all the characters
    for (int i = 0; i < N; i++) {
      a[(int)str[i] - (int)('a')]++;
    }
 
    // Prefix array
    int[] prefix = new int[26];
    prefix[0] = a[0];
    for (int i = 1 ; i < 26 ; i++) {
      prefix[i] = prefix[i - 1] + a[i];
    }
 
    // Get the starting index of the kth
    // lexicographically string
    int startingIndex = (K - 1) * M;
    int var = 0;
 
    // To track the size of string
    int size = 0;
 
    String kthString = "";
 
    for (int i = 0 ; i < 26 ; i++) {
      // Prefix array is smaller than
      // startingIndex or element is not present
      if (prefix[i] < startingIndex || a[i] == 0) {
        continue;
      }
      // This case is when prefix array
      // exceeds the startingIndex for
      // the first time
      else if (var == 0) {
        var = prefix[i] - startingIndex;
        for (int j = 0 ; j < var ; j++) {
          kthString += (char)(97 + i);
          size++;
          if (size == M){
            break;
          }
        }
      }
      // Prefix array exceeding startingIndex
      // other than first time
      else {
        for (int j = 0 ; j < prefix[i] - prefix[i - 1] ; j++) {
          kthString += (char)(97 + i);
          size++;
          if (size == M){
            break;
          }
        }
      }
      // Breaking from the loop if we
      // get the string of M size
      if (size == M){
        break;
      }
    }
 
    // Return the resultant string
    return kthString;
  }
 
  public static void Main(string[] args)
  {
 
    int N = 6;
    int M = 3;
    int K = 1;
    String str = "xeabck";
 
    // Function call
    Console.WriteLine(getKthString(N, M, K, str));
 
  }
}
 
// This code is contributed by subhamgoyal2014.


Javascript




// JavaScript program for the above approach:
 
// Function to get the kth substring
function getKthString(N, M, K, str)
{
    let a = new Array(26).fill(0);
 
    // Storing the frequency of all the characters
    for (var i = 0; i < N; i++)
        a[str[i].charCodeAt(0) - 'a'.charCodeAt(0)]++;
 
    // Prefix array
    let prefix = new Array(26).fill(0);
    prefix[0] = a[0];
    for (var i = 1; i < 26; i++)
        prefix[i] = prefix[i - 1] + a[i];
 
    // Get the starting index of the kth
    // lexicographically string
    let startingIndex = (K - 1) * M;
    let var_ = 0;
 
    // To track the size of string
    let size = 0;
 
    let kthString = "";
 
    for (var i = 0; i < 26; i++)
    {
        // Prefix array is smaller than
        // startingIndex or element is not present
        if (prefix[i] < startingIndex || a[i] == 0)
            continue;
        // This case is when prefix array
        // exceeds the startingIndex for
        // the first time
        else if (var_ == 0)
        {
            var_ = prefix[i] - startingIndex;
            for (var j = 0; j < var_; j++)
            {
                kthString += String.fromCharCode(97 + i);
                size += 1;
                if (size == M)
                    break;
            }
        }
        // Prefix array exceeding startingIndex
        // other than first time
        else
        {
            for (var j = 0; j < (prefix[i] - prefix[i - 1]); j++)
            {
                kthString += String.fromCharCode(97 + i);
                size += 1;
                if (size == M)
                    break;
            }
        }
        // Breaking from the loop if we
        // get the string of M size
        if (size == M)
            break
    }
 
    // Return the resultant string
    return kthString;
}
 
// Driver code
let N = 6;
let M = 3;
let K = 1;
let string = "xeabck";
 
// Function call
console.log(getKthString(N, M, K, string));
 
     
// This code is contributed by phasing17


Output

abc

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



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads