📌  相关文章
📜  排列数组元素,以使元素的最后一位等于下一个元素的第一位

📅  最后修改于: 2021-04-17 09:53:21             🧑  作者: Mango

给定整数数组arr [] ,任务是排列数组元素,以使元素的最后一位等于下一个元素的第一位。

例子:

天真的方法:找到数组元素的所有排列,然后打印满足所需条件的排列好的数组。这种方法的时间复杂度为O(N!)

高效的方法:创建一个有向图,如果节点A表示的数字的最后一位等于节点B表示的数字的第一位,则从节点A到节点B会有一条有向边。现在,找到形成图的欧拉路径。上述算法的复杂度为O(E * E) ,其中E是图中的边数。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
// To store the array elements
vector arr;
 
// Adjacency list for the graph nodes
vector > graph;
 
// To store the euler path
vector path;
 
// Print eulerian path
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.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 path
void 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 code
int 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
// Java implementation of the approach
import java.util.*;
 
class GFG{
 
// To store the array elements
static List arr = new ArrayList();
 
// Adjacency list for the graph nodes
static List> graph = new ArrayList>();
 
// To store the euler path
static List path = new ArrayList();
 
// Print eulerian path
static 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 path
static void connect()
{
    int n = arr.size();
    graph = new ArrayList>(n);
 
    for(int i = 0; i < n; i++)
    {
        graph.add(new ArrayList());
    }
     
    // 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 code
public 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
# 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 code
if __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#
// C# implementation of the approach
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG
{
 
// To store the array elements
static List arr = new List();
 
// Adjacency list for the graph nodes
static List > graph=  new List>();
 
// To store the euler path
static List path = new List();
 
// Print eulerian path
static 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 path
static void connect()
{
    int n = arr.Count;
    graph=new List>(n);
 
    for(int i = 0; i < n; i++)
    {
        graph.Add(new List());
    }
     
    // 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 code
public 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

时间复杂度: O(N * log(N))

辅助空间:O(N)