Create a string with unique characters from the given N substrings
Given an array arr[] containing N substrings consisting of lowercase English letters, the task is to return the minimum length string that contains all given parts as a substring. All characters in this new answer string should be distinct. If there are multiple strings with the following property present, you have to print the string with minimum length.
Examples:
Input: N = 3, arr[] = {“bcd”, “ab”, “cdef”}
Output: “abcdef”
Explanation:
- abcdef contains “bcd” from [1-3] index (0-based indexing)
- abcdef contains “ab” from [0-2]
- abcdef contains “cdef” from [2-5]
It can be proven that “abcdef” is the smallest string consisting of the given 3 substring fragments from input.
Input: N = 3, arr[]= {“dfghj”, “ghjkl”, “asdfg”];
Output: “asdfghjkl”
Explanation:
- asdfghjkl contains “dfghj” from [2-6] index (0-based indexing)
- asdfghjkl contains “ghjkl” from [4-8]
- asdfghjkl contains “asdfg” from [0-4]
It can be proven that “asdfghjkl ” is the smallest string consisting of the given 3 substring fragments from input.
Approach: Implement the below idea to solve the problem:
- While traversing a string, if a character in left and right exists we will be storing this, information in the left[] and right[] array. If an element of a substring does not have a left element,
this means that it’s the first element. We will be marking these elements as -1(indicating the start of a substring).- Finally, print the final answer. We will be starting with the character having a – 1 value in the left[] array because it’s the start of the string and will gonna print its right element from the right[] array, now this right element is the new element and now we will be finding it’s the right element from right[] array the same way until we reach -2 (as right) for an element, which indicates the end of the string.
Follow the steps to solve the above idea:
- Create two arrays left[] and right[] having size = 26 (a to z)
- Initialize each value for left[] and right[] = -2 (indicating the following characters has no left and right elements yet)
- Iterate over each substring given in the input array
- if it’s the first character mark it’s left = -1 (indicating the start of a substring)
- else if, it’s left == -2 (does not exist yet) update it with the left character if it exists in the current substring
- update the right[] value by accessing s[i+1]th character of the current substring if it exists.
- To print the final result find out the index containing -2 in the left[] array
- print this element and update current = right[current]
- repeat until right != -2
Below is the code to implement the approach:
C++
// C++ code for the above approach: #include <bits/stdc++.h> using namespace std; // Function to create string containing // all substrings of array arr[] void formedString( int n, vector<string>& arr) { // Defining left and right array to // store the left and right element // for each character (a to z) vector< int > left(26), right(26); // Initializing left and right values // for each character = -2 (indicating // the following characters has no left // and right elements yet) for ( int i = 0; i < 26; i++) left[i] = right[i] = -2; for (string s : arr) { // Iterating over each substring s // given in the array for ( int j = 0; j < s.size(); j++) { // Finding the character index // to store int t = s[j] - 'a' ; // If it's the first character // of substring (means left // does not exist) if (j > 0) { int t1 = s[j - 1] - 'a' ; left[t] = t1; } else if (left[t] == -2) left[t] = -1; // If right element exists for // jth character find it and // store in right[t] if (j < s.size() - 1) { int t1 = s[j + 1] - 'a' ; right[t] = t1; } } } // Code to output the final string int j; // Looping over all characters from // (a to z) to find out the first // index (having left = -1) for ( int i = 0; i < 26; i++) if (left[i] == -1) { // If 1st index is found print // it and update j = right[j] // and repeat until -2 is // encountered -2 indicates // the end int j = i; while (j != -2) { // Converting the integer // value into character cout << ( char )(j + 97); j = right[j]; } } } // Driver code int main() { int n = 3; vector<string> arr = { "dfghj" , "ghjkl" , "asdfg" }; // Function call formedString(n, arr); } |
Java
// Java code for the above approach: import java.io.*; import java.util.*; class GFG { // Function to create string containing // all substrings of array arr[] static void formedString( int n, String arr[]) { // Defining left and right array to // store the left and right element // for each character (a to z) int [] left = new int [ 26 ]; int [] right = new int [ 26 ]; // Initializing left and right values // for each character = -2 (indicating // the following characters has no left // and right elements yet) for ( int i = 0 ; i < 26 ; i++) left[i] = right[i] = - 2 ; for (String s : arr) { // Iterating over each substring s // given in the array for ( int j = 0 ; j < s.length(); j++) { // Finding the character index // to store int t = s.charAt(j) - 'a' ; // If it's the first character // of substring (means left // does not exist) if (j > 0 ) { int t1 = s.charAt(j - 1 ) - 'a' ; left[t] = t1; } else if (left[t] == - 2 ) left[t] = - 1 ; // If right element exists for // jth character find it and // store in right[t] if (j < s.length() - 1 ) { int t1 = s.charAt(j + 1 ) - 'a' ; right[t] = t1; } } } // Code to output the final string int j; // Looping over all characters from // (a to z) to find out the first // index (having left = -1) for ( int i = 0 ; i < 26 ; i++) if (left[i] == - 1 ) { // If 1st index is found print // it and update j = right[j] // and repeat until -2 is // encountered -2 indicates // the end j = i; while (j != - 2 ) { // Converting the integer // value into character System.out.print(( char )(j + 97 )); j = right[j]; } } } // Driver code public static void main(String[] args) { int n = 3 ; String[] arr = { "dfghj" , "ghjkl" , "asdfg" }; // Function Call formedString(n, arr); } } |
Python3
# Python3 code for the above approach # Function to create string containing # all substrings of array arr[] def formedstring(n, arr): # Defining left and right array to # store the left and right element # for each character (a to z) left = [ - 2 for i in range ( 26 )] right = [ - 2 for i in range ( 26 )] for s in arr: # Iterating over each substring s # given in the array for j in range ( len (s)): # Find the character index to store t = ord (s[j]) - ord ( 'a' ) # If it is the first character # of substring (means left does not exist) if j > 0 : t1 = ord (s[j - 1 ]) - ord ( 'a' ) left[t] = t1 elif left[t] = = - 2 : left[t] = - 1 # If right element exists for jth character # find it and store in right[t] if j < len (s) - 1 : t1 = ord (s[j + 1 ]) - ord ( 'a' ) right[t] = t1 # Code to output the final string j = None # Looping over all characters from # (a to z) to find out the first # index (having left = -1) for i in range ( 26 ): if left[i] = = - 1 : # If 1st index is found print # it and update j = right[j] # and repeat until -2 is # encountered -2 indicates the end j = i while j ! = - 2 : # Converting the integer # value into character print ( chr (j + 97 ), end = "") j = right[j] # Driver code if __name__ = = "__main__" : n = 3 arr = [ "dfghj" , "ghjkl" , "asdfg" ] # Function call formedstring(n, arr) #This code is contributed by nikhilsainiofficial546 |
C#
// C# code for the above approach: using System; public class GFG{ // Function to create string containing // all substrings of array arr[] static void formedString( int n, string [] arr) { // Defining left and right array to // store the left and right element // for each character (a to z) int [] left = new int [26]; int [] right = new int [26]; // Initializing left and right values // for each character = -2 (indicating // the following characters has no left // and right elements yet) for ( int i = 0; i < 26; i++) left[i] = right[i] = -2; foreach ( string s in arr) { // Iterating over each substring s // given in the array for ( int k = 0; k < s.Length;k++) { // Finding the character index // to store int t = s[k] - 'a' ; // If it's the first character // of substring (means left // does not exist) if (k > 0) { int t1 = s[k - 1] - 'a' ; left[t] = t1; } else if (left[t] == -2) left[t] = -1; // If right element exists for // jth character find it and // store in right[t] if (k < s.Length - 1) { int t1 = s[k + 1] - 'a' ; right[t] = t1; } } } // Code to output the final string int j; // Looping over all characters from // (a to z) to find out the first // index (having left = -1) for ( int i = 0; i < 26; i++) if (left[i] == -1) { // If 1st index is found print // it and update j = right[j] // and repeat until -2 is // encountered -2 indicates // the end j = i; while (j != -2) { // Converting the integer // value into character Console.Write(( char )(j + 97)); j = right[j]; } } } // Driver code static public void Main (){ int n = 3; String[] arr = { "dfghj" , "ghjkl" , "asdfg" }; // Function Call formedString(n, arr); } } |
Javascript
function formedString(n, arr) { // Defining left and right array to // store the left and right element // for each character (a to z) let left = Array(26).fill(-2); let right = Array(26).fill(-2); arr.forEach((s) => { // Iterating over each substring s // given in the array for (let j = 0; j < s.length; j++) { // Find the character index to store let t = s.charCodeAt(j) - 'a' .charCodeAt(0); // If it is the first character // of substring (means left does not exist) if (j > 0) { let t1 = s.charCodeAt(j - 1) - 'a' .charCodeAt(0); left[t] = t1; } else if (left[t] == -2) { left[t] = -1; } // If right element exists for jth character // find it and store in right[t] if (j < s.length - 1) { let t1 = s.charCodeAt(j + 1) - 'a' .charCodeAt(0); right[t] = t1; } } }); // Code to output the final string let j = null ; // Looping over all characters from // (a to z) to find out the first // index (having left = -1) for (let i = 0; i < 26; i++) { if (left[i] == -1) { // If 1st index is found print // it and update j = right[j] // and repeat until -2 is // encountered -2 indicates the end j = i; while (j != -2) { // Converting the integer // value into character process.stdout.write(String.fromCharCode(j + 97)); j = right[j]; } } } } // Driver code if (require.main === module) { let n = 3; let arr = [ "dfghj" , "ghjkl" , "asdfg" ]; // Function call formedString(n, arr); } |
asdfghjkl
Time Complexity: O(N*C), Where C is equal to the maximum size of a substring.
Auxiliary Space: O(1) (two extra arrays left[] and right[] of size 26 are used which is constant for all input sizes).
Related Articles:
Please Login to comment...