Permutation

Published: May 24, 2016

Well, how bad naive implementation of generating permutation? Permutation is a well-known problem in mathematics as well as programming. If a set of three characters, {A, B, C}, its permutation is:

ABC, ACB, BAC, BCA, CAB, CBA

Three characters generate six patterns, which is 3*2*1, a factorial of its size.

The easiest implementation is a brute-force, recursing all. How many times will it repeat? The answer is a factorial of total number of given characters. Crap! In terms of Big-O complexity, the factorial is the worst. See Big-O Complexitiy Chart at Big-O Cheat Sheet. To generate only 10 letters of permutation, 3628800 times repetition must be done.

How to effectively find permutation

This is a famous problem, so it’s easy to find the solution for “how to effectively find/generate permutation.” As far as I googled, these three were the best.

Overall, above three take the same approach. The trick is lexicographical order. The lexicographical order is not the goal but is the way to effectively generates permutations. Above three use the lexicographical order to find next permutations one by one. When there’s no next permutation, all permutations are generated.

Permutation generation code

Steps of the algorithm are:

  1. (optional) sort given string or array
  2. find longest non-increasing suffix such that array[index] <= array[index+1]
  3. identify the pivot index such that the first array[index] > array[index+1]
  4. find the ceil (successor), the right most index such that array[pivot] < array[succ]
  5. swap the pivot and successor, array[pivot] and array[succ]
  6. reverse the suffix from array[pivot+1] to array[array.length-1] if the array has been sorted at step 1, sort suffix instead of reversing

The sorted version of permutation in Java will be something like this:

import java.util.Arrays;

public class AllPermutations {
    static void sortedPermutations(char[] array) {
        Arrays.parallelSort(array);
        boolean isFinished = false;
        int count = 0;
        while (!isFinished) {
            if (count !=0 && count % 10 == 0) System.out.println();
            System.out.print((new String(array)) + " "); count++;

            int index = array.length-2;
            // find non-increasing suffix
            while(index >= 0) {
                if (array[index] <= array[index+1]) break;
                index--;
            }
            if (index == -1) {
                isFinished = true;
            } else {
                // the pivot is array[index]
                // find the rightmost successor to the pivot in suffix
                int succ = array.length-1;
                while(array[succ] <= array[index]) succ--;
                // swap the pivot and successor
                char tmp = array[index];
                array[index] = array[succ];
                array[succ] = tmp;
                // sort suffix
                Arrays.parallelSort(array, index+1, array.length);
            }
        }
    }

    public static void main(String[] args) {
      sortedPermutations("ABCDE".toCharArray());
    }
}

The above code prints:

ABCDE ABCED ABDCE ABDEC ABECD ABEDC ACBDE ACBED ACDBE ACDEB
ACEBD ACEDB ADBCE ADBEC ADCBE ADCEB ADEBC ADECB AEBCD AEBDC
AECBD AECDB AEDBC AEDCB BACDE BACED BADCE BADEC BAECD BAEDC
BCADE BCAED BCDAE BCDEA BCEAD BCEDA BDACE BDAEC BDCAE BDCEA
BDEAC BDECA BEACD BEADC BECAD BECDA BEDAC BEDCA CABDE CABED
CADBE CADEB CAEBD CAEDB CBADE CBAED CBDAE CBDEA CBEAD CBEDA
CDABE CDAEB CDBAE CDBEA CDEAB CDEBA CEABD CEADB CEBAD CEBDA
CEDAB CEDBA DABCE DABEC DACBE DACEB DAEBC DAECB DBACE DBAEC
DBCAE DBCEA DBEAC DBECA DCABE DCAEB DCBAE DCBEA DCEAB DCEBA
DEABC DEACB DEBAC DEBCA DECAB DECBA EABCD EABDC EACBD EACDB
EADBC EADCB EBACD EBADC EBCAD EBCDA EBDAC EBDCA ECABD ECADB
ECBAD ECBDA ECDAB ECDBA EDABC EDACB EDBAC EDBCA EDCAB EDCBA 

Latest Posts

Application Development by Rails Action Cable

The previous two blog posts introduced WebSocket and how to implement a WebSocket application on Ruby on Rails. This blog post digs deeper. It is a memo on creating a more realistic application by Action Cable.

Real-time App on Rails by Action Cable

The previous blog post, WebSocket on Rails by Action Cable, focused on WebSocket as a protocol. As in the previous post, by default, Rails app responds to WebSocket connection requests without any hassle. However, other than connecting and sending ping frames, it doesn’t do anything. This blog post focuses on an application side and explains how we can create a full-duplex, bidirectional app.

WebSocket on Rails by Action Cable

In the web application domain, we hear some protocol names. Absolutely, HTTP or HTTPS is the most famous protocol that all web developers know. Although there’s a mechanism of Keep-Alive, a single request/response sequence with a single client/server is all done by HTTP. The client initiates the HTTP request to the server. Once the client receives the HTTP response from the server, communication finishes. As far as HTTP is used, the server just waits and waits. Only when the request comes in, the server can send back some data to the client. This communication style is surprisingly capable of doing many things, so most web applications are satisfied with HTTP.