Given n strings, concatenate them in an order that produces the lexicographically smallest possible string.
Examples:
Input : a[] = ["c", "cb", "cba"]
Output : cbacbc
Possible strings are ccbcba, ccbacb,
cbccba, cbcbac, cbacbc and cbaccb.
Among all these strings, cbacbc is
the lexicographically smallest.
Input : a[] = ["aa", "ab", "aaa"]
Output : aaaaaab
One might think that sorting the given strings in the lexicographical order and then concatenating them produces the correct output. This approach produces the correct output for inputs like [“a”, “ab”, “abc”]. However, applying this method on [“c”, “cb”, “cba”] produces the wrong input and hence this approach is incorrect.
The correct approach is to use a regular sorting algorithm. When two strings a and b are compared to decide if they have to be swapped or not, do not check if a is lexicographically smaller than b or not. Instead check if appending b at the end of a produces a lexicographically smaller string or appending a at the end of b does.
This approach works because we want the concatenated string to be lexicographically small, not the individual strings to be in the lexicographical order.
Steps to solve this problem:
1. sort the string a from start index to end index.
2. declare an answer string as blank.
3. iterate through i=0 till n:
*update answer to answer+arr[i].
4. return answer.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
bool compare(string a, string b)
{
return (a+b < b+a);
}
string lexSmallest(string a[], int n)
{
sort(a, a+n, compare);
string answer = "" ;
for ( int i = 0; i < n; i++)
answer += a[i];
return answer;
}
int main()
{
string a[] = { "c" , "cb" , "cba" };
int n = sizeof (a)/ sizeof (a[0]);
cout << lexSmallest(a, n);
return 0;
}
|
Java
class GFG {
static void sort(String a[], int n)
{
for ( int i = 0 ;i < n;i++)
{
for ( int j = i + 1 ;j < n;j++)
{
if ((a[i] + a[j]).compareTo(a[j] + a[i]) > 0 )
{
String s = a[i];
a[i] = a[j];
a[j] = s;
}
}
}
}
static String lexsmallest(String a[], int n)
{
sort(a,n);
String answer = "" ;
for ( int i = 0 ; i < n; i++)
answer += a[i];
return answer;
}
public static void main(String args[])
{
String a[] = { "c" , "cb" , "cba" };
int n = 3 ;
System.out.println( "lexicographically smallest string = "
+ lexsmallest(a, n));
}
}
|
Python 3
def lexSmallest(a, n):
for i in range ( 0 ,n):
for j in range (i + 1 ,n):
if (a[i] + a[j]>a[j] + a[i]):
s = a[i]
a[i] = a[j]
a[j] = s
answer = ""
for i in range ( n):
answer + = a[i]
return answer
if __name__ = = "__main__" :
a = [ "c" , "cb" , "cba" ]
n = len (a)
print (lexSmallest(a, n))
|
C#
using System;
class GFG {
static void sort(String []a, int n)
{
for ( int i = 0;i < n;i++)
{
for ( int j = i + 1;j < n;j++)
{
if ((a[i] + a[j]).CompareTo(a[j] +
a[i]) > 0)
{
String s = a[i];
a[i] = a[j];
a[j] = s;
}
}
}
}
static String lexsmallest(String []a, int n)
{
sort(a,n);
String answer = "" ;
for ( int i = 0; i < n; i++)
answer += a[i];
return answer;
}
public static void Main()
{
String []a = { "c" , "cb" , "cba" };
int n = 3;
Console.Write( "lexicographically smallest string = "
+ lexsmallest(a, n));
}
}
|
Javascript
<script>
function sort(a,n)
{
for (let i = 0;i < n;i++)
{
for (let j = i + 1;j < n;j++)
{
if ((a[i] + a[j])>(a[j] + a[i]) )
{
let s = a[i];
a[i] = a[j];
a[j] = s;
}
}
}
}
function lexsmallest(a,n)
{
sort(a,n);
let answer = "" ;
for (let i = 0; i < n; i++)
answer += a[i];
return answer;
}
let a=[ "c" , "cb" , "cba" ];
let n = 3;
document.write( "lexicographically smallest string = "
+ lexsmallest(a, n));
</script>
|
Complexity Analysis:
- Time complexity : The above code runs in O(M * N * logN) where N is number of strings and M is maximum length of a string.
- Auxiliary Space: O(n)
This article is contributed by Aarti_Rathi. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.