Arrange array elements such that last digit of an element is equal to first digit of the next element - GeeksforGeeks

05 Feb, 2021
Given an array arr[] of integers, the task is to arrange the array elements such that the last digit of an element is equal to first digit of the next element.
Examples: 
Input: arr[] = {123, 321} Output: 123 321
Input: arr[] = {451, 378, 123, 1254} Output: 1254 451 123 378  
Naive approach: Find all the permutations of the array elements and then print the arranged array which meets the required condition. The time complexity of this approach is O(N!)
Efficient approach: Create a directed graph where there will be a directed edge from a node A to node B if the last digit of the number represented by Node A is equal to the first digit of the number represented by Node B. Now, find the Eulerian path for the graph formed. The complexity of the above algorithm is O(E * E) where E is the number of edges in the graph.
Below is the implementation of the above approach:
C++
Java
Python3
C#
// C++ implementation of the approach#include <bits/stdc++.h>using namespace std; // To store the array elementsvector<string> arr; // Adjacency list for the graph nodesvector<vector<int> > graph; // To store the euler pathvector<string> path; // Print eulerian pathbool print_euler(int i, int visited[], int count){    // Mark node as visited    // and increase the count    visited[i] = 1;    count++;     // If all the nodes are visited    // then we have traversed the euler path    if (count == graph.size()) {        path.push_back(arr[i]);        return true;    }     // Check if the node lies in euler path    bool b = false;     // Traverse through remaining edges    for (int j = 0; j < graph[i].size(); j++)        if (visited[graph[i][j]] == 0) {            b |= print_euler(graph[i][j], visited, count);        }     // If the euler path is found    if (b) {        path.push_back(arr[i]);        return true;    }     // Else unmark the node    else {        visited[i] = 0;        count--;        return false;    }} // Function to create the graph and// print the required pathvoid connect(){    int n = arr.size();    graph.clear();    graph.resize(n);     // Connect the nodes    for (int i = 0; i < n; i++) {        for (int j = 0; j < n; j++) {            if (i == j)                continue;             // If the last character matches with the            // first character            if (arr[i][arr[i].length() - 1] == arr[j][0]) {                graph[i].push_back(j);            }        }    }     // Print the path    for (int i = 0; i < n; i++) {        int visited[n] = { 0 }, count = 0;         // If the euler path starts        // from the ith node        if (print_euler(i, visited, count))            break;    }     // Print the euler path    for (int i = path.size() - 1; i >= 0; i--) {        cout << path[i];        if (i != 0)            cout << " ";    }}// Driver codeint main(){    arr.push_back("451");    arr.push_back("378");    arr.push_back("123");    arr.push_back("1254");     // Create graph and print the path    connect();     return 0;}
// Java implementation of the approachimport java.util.*; class GFG{ // To store the array elementsstatic List<String> arr = new ArrayList<String>(); // Adjacency list for the graph nodesstatic List<List<Integer>> graph = new ArrayList<List<Integer>>(); // To store the euler pathstatic List<String> path = new ArrayList<String>(); // Print eulerian pathstatic boolean print_euler(int i, int []visited,                           int count){         // Mark node as visited    // and increase the count    visited[i] = 1;    count++;     // If all the nodes are visited    // then we have traversed the euler path    if (count == graph.size())    {        path.add(arr.get(i));        return true;    }     // Check if the node lies in euler path    boolean b = false;     // Traverse through remaining edges    for(int j = 0; j < graph.get(i).size(); j++)        if (visited[graph.get(i).get(j)] == 0)        {            b |= print_euler(graph.get(i).get(j),                             visited, count);        }     // If the euler path is found    if (b)    {        path.add(arr.get(i));        return true;    }     // Else unmark the node    else    {        visited[i] = 0;        count--;        return false;    }} // Function to create the graph and// print the required pathstatic void connect(){    int n = arr.size();    graph = new ArrayList<List<Integer>>(n);     for(int i = 0; i < n; i++)    {        graph.add(new ArrayList<Integer>());    }         // Connect the nodes    for(int i = 0; i < n; i++)    {        for(int j = 0; j < n; j++)        {            if (i == j)                continue;             // If the last character matches with the            // first character            if (arr.get(i).charAt((arr.get(i).length()) - 1) ==                arr.get(j).charAt(0))            {                graph.get(i).add(j);            }        }    }     // Print the path    for(int i = 0; i < n; i++)    {        int []visited = new int[n];        int count = 0;         // If the euler path starts        // from the ith node        if (print_euler(i, visited, count))            break;    }     // Print the euler path    for(int i = path.size() - 1; i >= 0; i--)    {        System.out.print(path.get(i));                 if (i != 0)            System.out.print(" ");    }} // Driver codepublic static void main(String []args){    arr.add("451");    arr.add("378");    arr.add("123");    arr.add("1254");     // Create graph and print the path    connect();}} // This code is contributed by pratham76
# Python3 implementation of the approach # Print eulerian path  def print_euler(i, visited, count):     # Mark node as visited    # and increase the count    visited[i] = 1    count += 1     # If all the nodes are visited then    # we have traversed the euler path    if count == len(graph):        path.append(arr[i])        return True     # Check if the node lies in euler path    b = False     # Traverse through remaining edges    for j in range(0, len(graph[i])):        if visited[graph[i][j]] == 0:            b |= print_euler(graph[i][j], visited, count)     # If the euler path is found    if b:        path.append(arr[i])        return True     # Else unmark the node    else:        visited[i] = 0        count -= 1        return False # Function to create the graph# and print the required path  def connect():     n = len(arr)    # Connect the nodes    for i in range(0, n):        for j in range(0, n):            if i == j:                continue             # If the last character matches            # with the first character            if arr[i][-1] == arr[j][0]:                graph[i].append(j)     # Print the path    for i in range(0, n):        visited = [0] * n        count = 0         # If the euler path starts        # from the ith node        if print_euler(i, visited, count):            break     # Print the euler path    for i in range(len(path) - 1, -1, -1):        print(path[i], end="")        if i != 0:            print(" ", end="")  # Driver codeif __name__ == "__main__":     # To store the array elements    arr = []    arr.append("451")    arr.append("378")    arr.append("123")    arr.append("1254")     # Adjacency list for the graph nodes    graph = [[] for i in range(len(arr))]     # To store the euler path    path = []     # Create graph and print the path    connect() # This code is contributed by Rituraj Jain
// C# implementation of the approachusing System;using System.Collections;using System.Collections.Generic; class GFG{ // To store the array elementsstatic List<string> arr = new List<string>(); // Adjacency list for the graph nodesstatic List<List<int> > graph=  new List<List<int>>(); // To store the euler pathstatic List<string> path = new List<string>(); // Print eulerian pathstatic bool print_euler(int i, int []visited, int count){    // Mark node as visited    // and increase the count    visited[i] = 1;    count++;     // If all the nodes are visited    // then we have traversed the euler path    if (count == graph.Count) {        path.Add(arr[i]);        return true;    }     // Check if the node lies in euler path    bool b = false;     // Traverse through remaining edges    for (int j = 0; j < graph[i].Count; j++)        if (visited[graph[i][j]] == 0) {            b |= print_euler(graph[i][j], visited, count);        }     // If the euler path is found    if (b) {        path.Add(arr[i]);        return true;    }     // Else unmark the node    else {        visited[i] = 0;        count--;        return false;    }} // Function to create the graph and// print the required pathstatic void connect(){    int n = arr.Count;    graph=new List<List<int>>(n);     for(int i = 0; i < n; i++)    {        graph.Add(new List<int>());    }         // Connect the nodes    for (int i = 0; i < n; i++) {        for (int j = 0; j < n; j++) {            if (i == j)                continue;             // If the last character matches with the            // first character            if (arr[i][(arr[i].Length) - 1] == arr[j][0]) {                graph[i].Add(j);            }        }    }     // Print the path    for (int i = 0; i < n; i++) {         int []visited = new int[n];        int count = 0;         // If the euler path starts        // from the ith node        if (print_euler(i, visited, count))            break;    }     // Print the euler path    for (int i = path.Count - 1; i >= 0; i--) {        Console.Write(path[i]);        if (i != 0)            Console.Write(" ");    }} // Driver codepublic static void Main(params string []args){    arr.Add("451");    arr.Add("378");    arr.Add("123");    arr.Add("1254");     // Create graph and print the path    connect();}} // This code is contributed by rutvik_56.
1254 451 123 378
 
Time Complexity : O(N* log(N))
Auxiliary Space: O(N)
 
rituraj_jain
ujjwalgoel1103
rutvik_56
pratham76
Advanced Data Structure
Arrays
Graph
Arrays
Graph
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Proof that Dominant Set of a Graph is NP-Complete
2-3 Trees | (Search, Insert and Deletion)
Extendible Hashing (Dynamic approach to DBMS)
Advantages of Trie Data Structure
Cartesian Tree
Arrays in Java
Arrays in C/C++
Program for array rotation
Stack Data Structure (Introduction and Program)
Top 50 Array Coding Problems for Interviews