简体   繁体   中英

Java - permutations of an array's elements - clearly explained

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 );
        }
    }
}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM