using System.Collections.Generic;
private static List<List<int>> FindPermutations(params int[] nums){
List<List<int>> result = new List<List<int>>();
Backtrack(result, new List<int>(), new bool[nums.Length], nums);
private static void Backtrack(List<List<int>> dList, List<int> list, bool[] used, int[] nums){
if(list.Count == nums.Length) {
dList.Add(new List<int>(list));
for(int i = 0; i < nums.Length; i++) {
Backtrack(dList, list, used, nums);
list.RemoveAt(list.Count - 1);
private static int FindOverlap(List<int> superPerm, List<int> perm){
for(int i = 1; i < superPerm.Count; i++) if(superPerm.Skip(superPerm.Count - i).SequenceEqual(perm.Take(i))) return i;
private static List<int> GetMinimalSuperPermutation(List<List<int>> permutations){
List<int> result = new List<int>(permutations[0]);
HashSet<int> used = new HashSet<int>{0};
while(used.Count < permutations.Count){
for(int i = 0; i < permutations.Count; i++){
if(used.Contains(i)) continue;
List<int> p2 = permutations[i];
int overlap = FindOverlap(result, p2);
if(overlap > maxOverlap){
result.AddRange(p1.Skip(maxOverlap));
public static List<int> ChainPermutations(List<List<int>> permutations){
List<int> result = new List<int>(permutations[0]);
HashSet<int> used = new HashSet<int>();
while(used.Count < permutations.Count){
var p1 = permutations.FirstOrDefault(p => !used.Contains(permutations.IndexOf(p)) && p[0] == result.Last());
result.AddRange(p1.Skip(1));
used.Add(permutations.IndexOf(p1));
public static void Main(){
int[] nums = new int[]{1, 2, 3, 4, 5, 6, 7};
List<List<int>> permutations = FindPermutations(nums);
Console.WriteLine(permutations.Count * 6);
List<int> chainedPermutations = GetMinimalSuperPermutation(permutations);
Console.WriteLine($"{string.Join("", chainedPermutations)}");
Console.WriteLine(chainedPermutations.Count);