Queries to answer the X-th smallest sub-string lexicographically
Last Updated :
11 Jul, 2025
Given a string str and Q queries. Every query consists of a number X, the task is to print the Xth lexicographically smallest sub-string of the given string str.
Examples:
Input: str = "geek", q[] = {1, 5, 10}
Output:
e
ek
k
"e", "e", "ee", "eek", "ek", "g", "ge", "gee", "geek" and "k" are
all the possible sub-strings in lexicographically sorted order.
Input: str = "abcgdhge", q[] = {15, 32}
Output:
bcgdhge
gdhge
Approach: Generate all the sub-strings and store them in any data structure and sort that data structure lexicographically. In the solution below, we have used a vector to store all the sub-strings and the inbuilt sort function sorts them in the given order. Now, for every query print vec[X - 1], which will be the Xth smallest sub-string.
Below is the implementation of the above approach:
C++
// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
// Function to pre-process the sub-strings
// in sorted order
void pre_process(vector<string>& substrings, string s)
{
int n = s.size();
// Generate all substrings
for (int i = 0; i < n; i++) {
string dup = "";
// Iterate to find all sub-strings
for (int j = i; j < n; j++) {
dup += s[j];
// Store the sub-string in the vector
substrings.push_back(dup);
}
}
// Sort the substrings lexicographically
sort(substrings.begin(), substrings.end());
}
// Driver code
int main()
{
string s = "geek";
// To store all the sub-strings
vector<string> substrings;
pre_process(substrings, s);
int queries[] = { 1, 5, 10 };
int q = sizeof(queries) / sizeof(queries[0]);
// Perform queries
for (int i = 0; i < q; i++)
cout << substrings[queries[i] - 1] << endl;
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
// Function to pre-process the sub-strings
// in sorted order
static void pre_process(String substrings[],String s)
{
int n = s.length();
// Generate all substrings
int count = 0;
for (int i = 0; i < n; i++)
{
String dup = "";
// Iterate to find all sub-strings
for (int j = i; j < n; j++)
{
dup += s.charAt(j);
// Store the sub-string in the vector
substrings[count++] = dup;
}
}
// Sort the substrings lexicographically
int size = substrings.length;
for(int i = 0; i < size-1; i++) {
for (int j = i + 1; j < substrings.length; j++)
{
if(substrings[i].compareTo(substrings[j]) > 0)
{
String temp = substrings[i];
substrings[i] = substrings[j];
substrings[j] = temp;
}
}
//sort(substrings.begin(), substrings.end());
}
}
// Driver code
public static void main(String args[])
{
String s = "geek";
// To store all the sub-strings
String substrings[] = new String[10];
pre_process(substrings, s);
int queries[] = { 1, 5, 10 };
int q = queries.length;
// Perform queries
for (int i = 0; i < q; i++)
System.out.println(substrings[queries[i]-1]);
}
}
// This code is contributed by
// Surendra_Gangwar
Python3
# Python3 implementation of the approach
# Function to pre-process the sub-strings
# in sorted order
def pre_process(substrings, s) :
n = len(s);
# Generate all substrings
for i in range(n) :
dup = "";
# Iterate to find all sub-strings
for j in range(i,n) :
dup += s[j];
# Store the sub-string in the vector
substrings.append(dup);
# Sort the substrings lexicographically
substrings.sort();
return substrings;
# Driver code
if __name__ == "__main__" :
s = "geek";
# To store all the sub-strings
substrings = [];
substrings = pre_process(substrings, s);
queries = [ 1, 5, 10 ];
q = len(queries);
# Perform queries
for i in range(q) :
print(substrings[queries[i] - 1]);
# This code is contributed by AnkitRai01
C#
// C# code for above given approach
using System;
class GFG
{
// Function to pre-process the sub-strings
// in sorted order
static void pre_process(String []substrings,String s)
{
int n = s.Length;
// Generate all substrings
int count = 0;
for (int i = 0; i < n; i++)
{
String dup = "";
// Iterate to find all sub-strings
for (int j = i; j < n; j++)
{
dup += s[j];
// Store the sub-string in the vector
substrings[count++] = dup;
}
}
// Sort the substrings lexicographically
int size = substrings.Length;
for(int i = 0; i < size-1; i++)
{
for (int j = i + 1; j < substrings.Length; j++)
{
if(substrings[i].CompareTo(substrings[j]) > 0)
{
String temp = substrings[i];
substrings[i] = substrings[j];
substrings[j] = temp;
}
}
//sort(substrings.begin(), substrings.end());
}
}
// Driver code
public static void Main(String []args)
{
String s = "geek";
// To store all the sub-strings
String []substrings = new String[10];
pre_process(substrings, s);
int []queries = { 1, 5, 10 };
int q = queries.Length;
// Perform queries
for (int i = 0; i < q; i++)
Console.WriteLine(substrings[queries[i]-1]);
}
}
/* This code contributed by PrinciRaj1992 */
JavaScript
<script>
// Javascript implementation of the approach
// Function to pre-process the sub-strings
// in sorted order
function pre_process(substrings, s)
{
var n = s.length;
// Generate all substrings
for (var i = 0; i < n; i++) {
var dup = "";
// Iterate to find all sub-strings
for (var j = i; j < n; j++) {
dup += s[j];
// Store the sub-string in the vector
substrings.push(dup);
}
}
// Sort the substrings lexicographically
substrings.sort();
}
// Driver code
var s = "geek";
// To store all the sub-strings
var substrings = [];
pre_process(substrings, s);
var queries = [1, 5, 10];
var q = queries.length;
// Perform queries
for (var i = 0; i < q; i++)
document.write( substrings[queries[i] - 1] + "<br>");
</script>
Time Complexity: O(N2*logN), as we are using an inbuilt sort function to sort an array of size N*N. Where N is the length of the string.
Auxiliary Space: O(N2), as we are using extra space for storing the substrings.
Similar Reads
Lexicographically smallest string with given string as prefix Given an array arr[] consisting of N strings and a string S if size M, the task is to find the lexicographically smallest string consisting of the string S as the prefix. If there doesn't exist any string starting with prefix S then print "-1". Examples: Input: arr[] = {"apple", "appe", "apl", "aapl
6 min read
Lexicographically smallest String by moving one Subsequence to the end Given a string S of size N, having lowercase alphabets, the task is to find the lexicographically minimum string after moving a subsequence to the end of the string only once. Example: Input: N = 3, S = "asa" Output: aasExplanation: The optimal subsequence is "s". Removed, and added at last. Hence t
9 min read
Lexicographically smallest string after M operations Given a string S and integer M. The task is to perform exactly M operations to get lexicographical smallest string. In each operation, select one character optimally from the string and update it with immediate next character ( aaa -> aab ), so that string remain lexicographical smallest.Multiple
7 min read
K-th lexicographically smallest unique substring of a given string Given a string S. The task is to print the K-th lexicographically the smallest one among the different substrings of s.A substring of s is a string obtained by taking out a non-empty contiguous part in s. For example, if s = ababc, a, bab and ababc are substrings of s, while ac, z, and an empty stri
5 min read
Find Lexicographically smallest String with Prefix Reversal Given a string str of length N. You have to choose a non-zero integer K (K <= N), such that in one operation you can take the prefix of the string of length K and append the reverse of it to itself, the task is to find the lexicographically smallest string you can get. Examples: Input: str = "bvd
5 min read
Find the lexicographically smallest string which satisfies the given condition Given an array, arr[] of N integers, where arr[i] represents the number of distinct characters in the prefix of length (i + 1) of a string S. The task is to find the lexicographically smallest string (if any exists) that satisfies the given prefix array. The string should be of lowercase English alp
10 min read