Open In App

Create a string with unique characters from the given N substrings

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

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);
}


Output

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:



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

Similar Reads