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++
#include <bits/stdc++.h>
using namespace std;
vector<string> arr;
vector<vector< int > > graph;
vector<string> path;
bool print_euler( int i, int visited[], int count)
{
visited[i] = 1;
count++;
if (count == graph.size()) {
path.push_back(arr[i]);
return true ;
}
bool b = false ;
for ( int j = 0; j < graph[i].size(); j++)
if (visited[graph[i][j]] == 0) {
b |= print_euler(graph[i][j], visited, count);
}
if (b) {
path.push_back(arr[i]);
return true ;
}
else {
visited[i] = 0;
count--;
return false ;
}
}
void connect()
{
int n = arr.size();
graph.clear();
graph.resize(n);
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
if (i == j)
continue ;
if (arr[i][arr[i].length() - 1] == arr[j][0]) {
graph[i].push_back(j);
}
}
}
for ( int i = 0; i < n; i++) {
int visited[n] = { 0 }, count = 0;
if (print_euler(i, visited, count))
break ;
}
for ( int i = path.size() - 1; i >= 0; i--) {
cout << path[i];
if (i != 0)
cout << " " ;
}
}
int main()
{
arr.push_back( "451" );
arr.push_back( "378" );
arr.push_back( "123" );
arr.push_back( "1254" );
connect();
return 0;
}
|
Java
import java.util.*;
class GFG{
static List<String> arr = new ArrayList<String>();
static List<List<Integer>> graph = new ArrayList<List<Integer>>();
static List<String> path = new ArrayList<String>();
static boolean print_euler( int i, int []visited,
int count)
{
visited[i] = 1 ;
count++;
if (count == graph.size())
{
path.add(arr.get(i));
return true ;
}
boolean b = false ;
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 (b)
{
path.add(arr.get(i));
return true ;
}
else
{
visited[i] = 0 ;
count--;
return false ;
}
}
static void connect()
{
int n = arr.size();
graph = new ArrayList<List<Integer>>(n);
for ( int i = 0 ; i < n; i++)
{
graph.add( new ArrayList<Integer>());
}
for ( int i = 0 ; i < n; i++)
{
for ( int j = 0 ; j < n; j++)
{
if (i == j)
continue ;
if (arr.get(i).charAt((arr.get(i).length()) - 1 ) ==
arr.get(j).charAt( 0 ))
{
graph.get(i).add(j);
}
}
}
for ( int i = 0 ; i < n; i++)
{
int []visited = new int [n];
int count = 0 ;
if (print_euler(i, visited, count))
break ;
}
for ( int i = path.size() - 1 ; i >= 0 ; i--)
{
System.out.print(path.get(i));
if (i != 0 )
System.out.print( " " );
}
}
public static void main(String []args)
{
arr.add( "451" );
arr.add( "378" );
arr.add( "123" );
arr.add( "1254" );
connect();
}
}
|
Python3
def print_euler(i, visited, count):
visited[i] = 1
count + = 1
if count = = len (graph):
path.append(arr[i])
return True
b = False
for j in range ( 0 , len (graph[i])):
if visited[graph[i][j]] = = 0 :
b | = print_euler(graph[i][j], visited, count)
if b:
path.append(arr[i])
return True
else :
visited[i] = 0
count - = 1
return False
def connect():
n = len (arr)
for i in range ( 0 , n):
for j in range ( 0 , n):
if i = = j:
continue
if arr[i][ - 1 ] = = arr[j][ 0 ]:
graph[i].append(j)
for i in range ( 0 , n):
visited = [ 0 ] * n
count = 0
if print_euler(i, visited, count):
break
for i in range ( len (path) - 1 , - 1 , - 1 ):
print (path[i], end = "")
if i ! = 0 :
print ( " " , end = "")
if __name__ = = "__main__" :
arr = []
arr.append( "451" )
arr.append( "378" )
arr.append( "123" )
arr.append( "1254" )
graph = [[] for i in range ( len (arr))]
path = []
connect()
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
class GFG
{
static List< string > arr = new List< string >();
static List<List< int > > graph= new List<List< int >>();
static List< string > path = new List< string >();
static bool print_euler( int i, int []visited, int count)
{
visited[i] = 1;
count++;
if (count == graph.Count) {
path.Add(arr[i]);
return true ;
}
bool b = false ;
for ( int j = 0; j < graph[i].Count; j++)
if (visited[graph[i][j]] == 0) {
b |= print_euler(graph[i][j], visited, count);
}
if (b) {
path.Add(arr[i]);
return true ;
}
else {
visited[i] = 0;
count--;
return false ;
}
}
static void connect()
{
int n = arr.Count;
graph= new List<List< int >>(n);
for ( int i = 0; i < n; i++)
{
graph.Add( new List< int >());
}
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
if (i == j)
continue ;
if (arr[i][(arr[i].Length) - 1] == arr[j][0]) {
graph[i].Add(j);
}
}
}
for ( int i = 0; i < n; i++) {
int []visited = new int [n];
int count = 0;
if (print_euler(i, visited, count))
break ;
}
for ( int i = path.Count - 1; i >= 0; i--) {
Console.Write(path[i]);
if (i != 0)
Console.Write( " " );
}
}
public static void Main( params string []args)
{
arr.Add( "451" );
arr.Add( "378" );
arr.Add( "123" );
arr.Add( "1254" );
connect();
}
}
|
Javascript
let arr = [];
let graph = [];
let path = [];
function print_euler(i, visited, count) {
visited[i] = 1;
count++;
if (count == graph.length) {
path.push(arr[i]);
return true ;
}
let b = false ;
for (let j = 0; j < graph[i].length; j++)
if (visited[graph[i][j]] == 0) {
b |= print_euler(graph[i][j], visited, count);
}
if (b) {
path.push(arr[i]);
return true ;
}
else {
visited[i] = 0;
count--;
return false ;
}
}
function connect() {
let n = arr.length;
graph.length = 0;
graph.length = n;
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
if (i == j) continue ;
if (arr[i][arr[i].length - 1] == arr[j][0]) {
graph[i].push(j);
}
}
}
for (let i = 0; i < n; i++) {
let visited = new Array(n).fill(0);
let count = 0;
if (print_euler(i, visited, count)) break ;
}
for (let i = path.length - 1; i >= 0; i--) {
console.log(path[i]);
if (i != 0) console.log( " " );
}
}
( function () {
arr.push( "451" );
arr.push( "378" );
arr.push( "123" );
arr.push( "1254" );
connect();
})();
|
Time Complexity : O(N* log(N))
Auxiliary Space: O(N)
Approach:(graph-based)
The approach is to create a graph where each number is a node and add an edge between two nodes if the last digit of one number matches the first digit of the other number. Then, we use an algorithm to find the Eulerian path in the graph, which represents the valid arrangement of numbers. Finally, we print the Eulerian path in reverse order to obtain the required arrangement of numbers.
C++
#include <bits/stdc++.h>
using namespace std;
vector<string> arr;
vector<vector< int >> graph;
vector<string> path;
bool print_euler( int i, int visited[], int count) {
visited[i] = 1;
count++;
if (count == graph.size()) {
path.push_back(arr[i]);
return true ;
}
bool b = false ;
for ( int j = 0; j < graph[i].size(); j++) {
if (visited[graph[i][j]] == 0) {
b |= print_euler(graph[i][j], visited, count);
}
}
if (b) {
path.push_back(arr[i]);
return true ;
}
else {
visited[i] = 0;
count--;
return false ;
}
}
void connect() {
int n = arr.size();
graph.clear();
graph.resize(n);
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
if (i == j) continue ;
if (arr[i][arr[i].length() - 1] == arr[j][0]) {
graph[i].push_back(j);
}
}
}
for ( int i = 0; i < n; i++) {
int visited[n] = {0}, count = 0;
if (print_euler(i, visited, count)) break ;
}
for ( int i = path.size() - 1; i >= 0; i--) {
cout << path[i];
if (i != 0) cout << " " ;
}
}
int main() {
arr.push_back( "451" );
arr.push_back( "378" );
arr.push_back( "123" );
arr.push_back( "1254" );
connect();
return 0;
}
|
Java
import java.util.ArrayList;
public class EulerPath {
static ArrayList<String> arr = new ArrayList<>();
static ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
static ArrayList<String> path = new ArrayList<>();
static boolean printEuler( int i, int [] visited, int count) {
visited[i] = 1 ;
count++;
if (count == graph.size()) {
path.add(arr.get(i));
return true ;
}
boolean b = false ;
for ( int j = 0 ; j < graph.get(i).size(); j++) {
if (visited[graph.get(i).get(j)] == 0 ) {
b |= printEuler(graph.get(i).get(j), visited, count);
}
}
if (b) {
path.add(arr.get(i));
return true ;
}
else {
visited[i] = 0 ;
count--;
return false ;
}
}
static void connect() {
int n = arr.size();
graph.clear();
for ( int i = 0 ; i < n; i++) {
graph.add( new ArrayList<>());
}
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < n; j++) {
if (i == j) continue ;
if (arr.get(i).charAt(arr.get(i).length() - 1 ) == arr.get(j).charAt( 0 )) {
graph.get(i).add(j);
}
}
}
for ( int i = 0 ; i < n; i++) {
int [] visited = new int [n];
int count = 0 ;
if (printEuler(i, visited, count)) {
break ;
}
}
for ( int i = path.size() - 1 ; i >= 0 ; i--) {
System.out.print(path.get(i));
if (i != 0 ) System.out.print( " " );
}
}
public static void main(String[] args) {
arr.add( "451" );
arr.add( "378" );
arr.add( "123" );
arr.add( "1254" );
connect();
}
}
|
Python3
arr = []
graph = []
path = []
def print_euler(i, visited, count):
global graph, arr, path
visited[i] = 1
count + = 1
if count = = len (graph):
path.append(arr[i])
return True
b = False
for j in graph[i]:
if visited[j] = = 0 :
b | = print_euler(j, visited, count)
if b:
path.append(arr[i])
return True
else :
visited[i] = 0
count - = 1
return False
def connect():
global graph, arr, path
n = len (arr)
graph = [[] for _ in range (n)]
for i in range (n):
for j in range (n):
if i = = j:
continue
if arr[i][ - 1 ] = = arr[j][ 0 ]:
graph[i].append(j)
for i in range (n):
visited = [ 0 ] * n
count = 0
if print_euler(i, visited, count):
break
print ( " " .join(path[:: - 1 ]))
if __name__ = = "__main__" :
arr = [ "451" , "378" , "123" , "1254" ]
connect()
|
C#
using System;
using System.Collections.Generic;
namespace EulerianPath
{
class GFG
{
static List< string > arr = new List< string >();
static List<List< int >> graph = new List<List< int >>();
static List< string > path = new List< string >();
static bool PrintEuler( int i, int [] visited, int count)
{
visited[i] = 1;
count++;
if (count == graph.Count)
{
path.Add(arr[i]);
return true ;
}
bool b = false ;
foreach ( int j in graph[i])
{
if (visited[j] == 0)
{
b |= PrintEuler(j, visited, count);
}
}
if (b)
{
path.Add(arr[i]);
return true ;
}
else
{
visited[i] = 0;
count--;
return false ;
}
}
static void Connect()
{
int n = arr.Count;
graph.Clear();
for ( int i = 0; i < n; i++)
{
graph.Add( new List< int >());
}
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < n; j++)
{
if (i == j) continue ;
if (arr[i][arr[i].Length - 1] == arr[j][0])
{
graph[i].Add(j);
}
}
}
for ( int i = 0; i < n; i++)
{
int [] visited = new int [n];
int count = 0;
if (PrintEuler(i, visited, count)) break ;
}
for ( int i = path.Count - 1; i >= 0; i--)
{
Console.Write(path[i]);
if (i != 0) Console.Write( " " );
}
}
static void Main( string [] args)
{
arr.Add( "451" );
arr.Add( "378" );
arr.Add( "123" );
arr.Add( "1254" );
Connect();
}
}
}
|
Time Complexity : O(n^2 * 2^n), where n is the number of strings in the input array. This is because for each pair of strings, we are comparing the last character of one string with the first character of the other string, and this takes O(n^2) time. In addition, we are using a recursive function to find the eulerian path, and the worst-case scenario involves traversing all the edges in the graph, which takes O(2^n) time.
Auxiliary Space:O(n + m), where n is the number of strings in the input array and m is the total number of edges in the graph. This is because we are using several auxiliary data structures such as vectors to store the array elements, adjacency list for the graph nodes, and the eulerian path. In addition, we are using an array to keep track of the visited nodes during the depth-first search, which takes O(n) space.