2

I've got an array of integers and need to find all the possible permutations of those elements using Java. So I'll have an array at the end that contains arrays, where each one is a permutation of the original single array. It must work with any size array.

I can do this for a string, but the array is tripping me up. My elements are integers so I can't use a straightforward string method, for example, if my ints are 1, 2, 14 I would be permuting the string 1214. Would it be possible to manipulate the string and permute it, and then get my required permutations at the end by somehow filtering?

I've looked around and seem to have found a few algorithms, but practically all of them are just reams of code with little to no explanation at all so I can't understand them. Has anyone got an algorithm for this out there, an algorithm that's explained!?

Here is my algorithm for the string:

static String[] getPermutations( String str ) { 
List<String> perms = new ArrayList<>();
    permute( "", str, perms );
    String[] list = perms.toArray( new String[ perms.size() ] );
    return list;
}

// This function recursively calls itself
static void permute( String prefix, String str, List<String> perms ) {
        int n = str.length();
        if ( n == 0 ) {
        perms.add(prefix);
        } else {
            for ( int i = 0; i < n; i++ ) {
            permute( prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n), perms );
        }
    }
}
Amoeba
  • 1,573
  • 4
  • 19
  • 25
  • Just visualize that a string is an array of characters. How you would have created permutation for it then? The algorithm would be almost similar for both of them – Prateek Oct 08 '13 at 19:08
  • I've edited my post to show my algorithm for the string. Any ideas how I could do it for an int[] ? – Amoeba Oct 08 '13 at 19:19
  • 1
    the biggest thing is that your `prefix + str.charAt(i)` is going to have to make a new array that is one bigger, and copy all of the prefix elements into it, and then str[i] at the end. Except it won't be str, it'll be an int array – Cruncher Oct 08 '13 at 19:27
  • It is not as simple problem I though it would be. Good question @Amoeba – Prateek Oct 08 '13 at 19:36

1 Answers1

0

Something like this for the permute method. Obviously the relevant changes will have to be made to the getPermutations method. The logic is really the same as the String example.

static void permute( List<Integer> prefix, List<Integer> ints, List<List<Integer>> perms ) {
        int n = ints.size();
        if ( n == 0 ) {
        perms.add(prefix);
        } else {
            for ( int i = 0; i < n; i++ ) {
                List<Integer> newPrefix = new ArrayList<Integer>();
                List<Integer> newInts = new ArrayList<Integer>();
                Collections.copy(prefix, newPrefix);
                Collections.copy(ints, newInts);

                newPrefix.add(ints.get(i));
                newInts.remove(i);

                permute( newPrefix, str.substring(0, i) + str.substring(i+1, n), perms );
            }
        }
}

If you're a stickler for efficiency, then you know what the final size of all the lists will be, and you know what the final size of the permutations list will be (N!) then you can use arrays, and save integers with where you are in the array so far. But this solution is the easiest to understand and implement

Cruncher
  • 7,641
  • 1
  • 31
  • 65