Lexicographical concatenation of all substrings of a string
Last Updated :
24 Jul, 2024
Given a string, find the concatenation of all substrings in lexicographic order.
Examples:
Input : s = "abc"
Output : aababcbbcc
The substrings of s in lexicographic order are "a", "b", "c", "ab", "abc", "bc". Concatenation of substrings is "a"+"ab"+"abc"+"b"+"bc"+"c" = "aababcbbcc".
Input : s = "cba"
Output : abbaccbcba
- Find all the substrings of string and store it in a string array. The size of array would be n*(n+1)/2 where n is length of input string.
- Sort the string array to make them all in lexicographical order.
- Concatenate the strings of string array in another empty string.
Implementation:
C++
// CPP Program to create concatenation of all
// substrings in lexicographic order.
#include <bits/stdc++.h>
using namespace std;
string lexicographicSubConcat(string s)
{
int n = s.length();
// Creating an array to store substrings
int sub_count = n*(n+1)/2;
string arr[sub_count];
// finding all substrings of string
int index = 0;
for (int i = 0; i < n; i++)
for (int len = 1; len <= n - i; len++)
arr[index++] = s.substr(i, len);
// Sort all substrings in lexicographic
// order
sort(arr, arr + sub_count);
// Concatenating all substrings
string res = "";
for (int i = 0; i < sub_count; i++)
res += arr[i];
return res;
}
int main()
{
string s = "abc";
cout << lexicographicSubConcat(s);
return 0;
}
Java
// Java Program to create concatenation of all
// substrings in lexicographic order.
import java.util.*;
class GFG
{
static String lexicographicSubConcat(String s)
{
int n = s.length();
// Creating an array to store substrings
int sub_count = n*(n+1)/2;
String []arr = new String[sub_count];
// finding all substrings of string
int index = 0;
for (int i = 0; i < n; i++)
for (int len = 1; len <= n - i; len++)
{
arr[index++] = s.substring(i, i+len);
}
// Sort all substrings in lexicographic
// order
Arrays.sort(arr);
// Concatenating all substrings
String res = "";
for (int i = 0; i < sub_count; i++)
res += arr[i];
return res;
}
// Driver code
public static void main(String[] args)
{
String s = "abc";
System.out.println(lexicographicSubConcat(s));
}
}
// This code has been contributed by 29AjayKumar
Python
# Python Program to create concatenation of all
# substrings in lexicographic order.
def lexicographicSubConcat(s):
n = len(s);
# Creating an array to store substrings
sub_count = (n * (n + 1))//2;
arr = [0]*sub_count;
# finding all substrings of string
index = 0;
for i in range(n):
for j in range(1,n - i + 1):
arr[index] = s[i:i + j];
index += 1;
# Sort all substrings in lexicographic
# order
arr.sort();
# Concatenating all substrings
res = "";
for i in range(sub_count):
res += arr[i];
return res;
s = "abc";
print(lexicographicSubConcat(s));
# This code is contributed by Princi Singh
C#
// C# Program to create concatenation of all
// substrings in lexicographic order.
using System;
class GFG
{
static String lexicographicSubConcat(String s)
{
int n = s.Length;
// Creating an array to store substrings
int sub_count = n*(n+1)/2;
String []arr = new String[sub_count];
// finding all substrings of string
int index = 0;
for (int i = 0; i < n; i++)
for (int len = 1; len <= n - i; len++)
{
arr[index++] = s.Substring(i, len);
}
// Sort all substrings in lexicographic
// order
Array.Sort(arr);
// Concatenating all substrings
String res = "";
for (int i = 0; i < sub_count; i++)
res += arr[i];
return res;
}
// Driver code
public static void Main(String[] args)
{
String s = "abc";
Console.WriteLine(lexicographicSubConcat(s));
}
}
/* This code contributed by PrinciRaj1992 */
JavaScript
<script>
// Javascript Program to create concatenation of all
// substrings in lexicographic order.
function lexicographicSubConcat(s)
{
var n = s.length;
// Creating an array to store substrings
var sub_count = n*parseInt((n+1)/2);
var arr = Array(sub_count);
// finding all substrings of string
var index = 0;
for (var i = 0; i < n; i++)
for (var len = 1; len <= n - i; len++)
arr[index++] = s.substring(i,i+ len);
// Sort all substrings in lexicographic
// order
arr.sort();
// Concatenating all substrings
var res = "";
for (var i = 0; i < sub_count; i++)
res += arr[i];
return res;
}
var s = "abc";
document.write( lexicographicSubConcat(s));
</script>
Time Complexity: O(n3)
Auxiliary Space: O(n)
Optimized Lexicographical Substring Concatenation Using Suffix Array and Sorting
This approach optimizes the concatenation of all substrings in lexicographical order by using a suffix array combined with a direct sorting method. Rather than explicitly generating all substrings and then sorting them, we utilize the properties of a suffix array to manage and sort the substrings indirectly. This technique leverages the suffix array's inherent ability to organize substrings efficiently, reducing both the time and space complexities associated with direct substring management and sorting.
- Suffix Array Construction: Build a list of starting indices for all suffixes of the string.
- Sort by Substring: Sort the suffix array based on the lexicographical order of substrings starting at each index.
- Direct Concatenation: Concatenate substrings directly by traversing through the sorted suffix array, extracting and appending substrings from the main string.
- Efficiency: This method avoids the overhead of storing all possible substrings explicitly, thereby saving significant space and potentially reducing sorting time.
Below is the implementation of above approach:
C++
#include <algorithm>
#include <iostream>
#include <vector>
// Function to compare suffixes based on the substrings they
// represent
bool compareSuffix(const std::string& s, int i, int j)
{
return s.substr(i) < s.substr(j);
}
// Function to concatenate lexicographically sorted
// substrings of a string
std::string
lexicographicSubConcatOptimized(const std::string& s)
{
int n = s.length();
// Generate suffix indices
std::vector<int> suffix_indices(n);
for (int i = 0; i < n; ++i) {
suffix_indices[i] = i;
}
// Sort suffix indices based on the substrings they
// represent
std::sort(suffix_indices.begin(), suffix_indices.end(),
[&](int i, int j) {
return compareSuffix(s, i, j);
});
// Concatenate all substrings in sorted order by
// expanding each suffix to the end of the string
std::string result;
for (int start : suffix_indices) {
for (int length = 1; length <= n - start;
++length) {
result += s.substr(start, length);
}
}
return result;
}
int main()
{
// Example usage
std::string s = "bca";
std::cout << lexicographicSubConcatOptimized(s)
<< std::endl;
return 0;
}
Java
import java.util.Arrays;
public class Main {
static String lexicographicSubConcatOptimized(String s)
{
int n = s.length();
// Generate suffix indices
Integer[] suffixIndices = new Integer[n];
for (int i = 0; i < n; i++) {
suffixIndices[i] = i;
}
// Sort suffix indices based on the substrings they
// represent
Arrays.sort(suffixIndices,
(a, b)
-> s.substring(a).compareTo(
s.substring(b)));
// Concatenate all substrings in sorted order by
// expanding each suffix to the end of the string
StringBuilder result = new StringBuilder();
for (int start : suffixIndices) {
for (int length = 1; length <= n - start;
length++) {
result.append(
s.substring(start, start + length));
}
}
return result.toString();
}
// Example usage
public static void main(String[] args)
{
String s = "bca";
System.out.println(
lexicographicSubConcatOptimized(s));
}
}
Python
def lexicographicSubConcatOptimized(s):
n = len(s)
# Generate suffix indices
suffix_indices = list(range(n))
# Sort suffix indices based on the substrings they represent
suffix_indices.sort(key=lambda x: s[x:])
# Concatenate all substrings in sorted order by expanding each suffix to the end of the string
result = ""
for start in suffix_indices:
for length in range(1, n - start + 1):
result += s[start:start + length]
return result
# Example usage
s = "bca"
print(lexicographicSubConcatOptimized(s))
JavaScript
function lexicographicSubConcatOptimized(s) {
let n = s.length;
// Generate suffix indices
let suffixIndices = Array.from({ length: n }, (_, i) => i);
// Sort suffix indices based on the substrings they represent
suffixIndices.sort((a, b) => s.substring(a).localeCompare(s.substring(b)));
// Concatenate all substrings in sorted order by expanding each suffix to the end of the string
let result = "";
for (let start of suffixIndices) {
for (let length = 1; length <= n - start; length++) {
result += s.substring(start, start + length);
}
}
return result;
}
// Example usage
let s = "bca";
console.log(lexicographicSubConcatOptimized(s));
Time Complexity: O(n^2 log n). This comes from sorting the suffixes which takes O(n log n) and the subsequent substring extraction and concatenation. Although each suffix can potentially contribute up to n characters, the actual substring operations (contribution to the final string) are bounded by the quadratic term.
Auxiliary Space: O(n). The primary space consumption comes from storing the suffix indices and the output string. The intermediate storage does not exceed the size of the original string significantly, as no extra structures are used for all possible substrings. This is a marked improvement over the original approach.
Similar Reads
Print all the combinations of a string in lexicographical order Given a string str, print of all the combinations of a string in lexicographical order.Examples: Input: str = "ABC" Output: A AB ABC AC ACB B BA BAC BC BCA C CA CAB CB CBA Input: ED Output: D DE E ED Approach: Count the occurrences of all the characters in the string using a map, then using recursio
9 min read
Lexicographical Maximum substring of string Given a string s we have to find the lexicographical maximum substring of a string Examples: Input : s = "ababaa" Output : babaa Explanation : "babaa" is the maximum lexicographic substring formed from this string Input : s = "asdfaa" Output : sdfaa The idea is simple, we traverse through all substr
6 min read
Print all distinct circular strings of length M in lexicographical order Given a string and an integer M, print all distinct circular strings of length M in lexicographical order. Examples: Input: str = "baaaa", M = 3 Output: aaa aab aba baa All possible circular substrings of length 3 are "baa" "aaa" "aaa" "aab" "aba" Out of the 6, 4 are distinct, and the lexicographica
5 min read
Generating distinct subsequences of a given string in lexicographic order Given a string s, make a list of all possible combinations of letters of a given string S. If there are two strings with the same set of characters, print the lexicographically smallest arrangement of the two stringsFor string abc, the list in lexicographic order subsequences are, a ab abc ac b bc c
4 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
All substrings of a given String Given a string s, containing lowercase alphabetical characters. The task is to print all non-empty substrings of the given string.Examples : Input : s = "abc"Output : "a", "ab", "abc", "b", "bc", "c"Input : s = "ab"Output : "a", "ab", "b"Input : s = "a"Output : "a"[Expected Approach] - Using Iterati
8 min read
Concatenate pairs of lexicographically adjacent characters Given a string S that contains only lowercase alphabets and no special characters except spaces, the task is to find lexicographically adjacent pairs of characters and concatenate the number of pairs of each word in the string. Examples: Input: S = "hello world"Output: 21Explanation: Input string co
7 min read
Lexicographically largest sub-sequence of the given string Given string str containing lowercase characters, the task is to find the lexicographically largest sub-sequence of str.Examples: Input: str = "abc" Output: c All possible sub-sequences are "a", "ab", "ac", "b", "bc" and "c" and "c" is the largest among them (lexicographically)Input: str = "geeksfor
7 min read
Lexicographically smallest string formed by concatenating any prefix and its mirrored form Given a string str of N characters, the task is to find the lexicographically smallest string that can be formed by concatenating any prefix and its mirrored form. Examples: Input: str = "geeksforgeeks"Output: geeeegExplanation: The lexicographically smallest string can be formed with the prefix "ge
5 min read
Lexicographically shortest string of length at most K which is not a substring of given String Given a string S, the task is to find the lexicographically shortest string of length less than or equal to K which is not a substring of the given string. If not possible, print -1. Examples: Input: S = zxabcehgf, K = 2Output: dExplanation: Lexicographically, the shortest string which is not a subs
9 min read