Search code examples
arraysalgorithmsortingpseudocode

What is the fastest algorithm to find all permutations one array can be arranged without having any two elements in the same order?


The practical application of this algorithm is to assign each person in a group of 2..N people a different target person from the same group of people for as many consecutive rounds as possible.

I'm representing the group of people as an array. The array holds the person identifiers as numbers, for example, 5 people will create an array [1, 2, 3, 4, 5]. The targets for each people can then be derived as:

  • Person 1 will have Person 2 as target
  • Person 2 will have Person 3
  • 3 => 4
  • 4 => 5
  • 5 => 1 (array will loop)

Array [1, 2, 3, 4, 5] can then yield the following targets in an abbreviated form: 1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 = 1

I need to find an algorithm that finds out all the permutations (different orders that the array elements can be sorted in) that have different consecutive elements.

For example, for the given array, result [2, 4, 3, 1, 5] is one, because you can't find 2 before 4, 4 before 3, 3 before 1, 1 before 5 and 5 before 2 (notice that I handle the array as looping) from the original array [1, 2, 3, 4, 5].

An array with 2 elements (or persons) will always have each other as targets. This means that algorithm with an input [1, 2] will only have one result: [1, 2]. It doesn't matter if you reorder the array elements as [2, 1] since we consider the array looping: 2 -> 1, 1 -> 2.

For [1, 2, 3] it's possible to find two permutations:
[1, 2, 3] (1 -> 2, 2 -> 3, 3 -> 1) and [2, 1, 3] (2 -> 1, 1 -> 3, 3 -> 2)

The algorithm should return all the permutations of the array as follows:

algorithm([1, 2, 3, 4, 5]) => [[1, 2, 3, 4, 5], [2, 4, 3, 1, 5], ...]

Solution

  • According to your comments, we can have outputs where 1 and 2 target each other and 3 and 4 target each other. (These outputs aren't representable in the output format you've chosen.)

    In that case, on every round i from 1 to N-1, just have everyone target the person i spots ahead of them.