A Util class for Lexicographically sorted permutations of number/string. Get N-th element of the result or next element for a given element without calculating all the permutations.
- Find the largest index k such that a[k] < a[k + 1]. If no such index exists, the permutation is the last permutation.
- Find the smallest index l such that a[k] < a[l]. Since k + 1 is such an index, l is well defined and satisfies condition k < l.
- Swap a[k] with a[l].
- Reverse the sequence from a[k + 1] up to and including the final element a[n].
package permute; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class LexicographicPermutation { public static boolean nextPermutation(int[] p) { int a = p.length - 2; while (a >= 0 && p[a] >= p[a + 1]) { a--; } if (a == -1) { return false; } int b = p.length - 1; while (p[b] <= p[a]) { b--; } int t = p[a]; p[a] = p[b]; p[b] = t; for (int i = a + 1, j = p.length - 1; i < j; i++, j--) { t = p[i]; p[i] = p[j]; p[j] = t; } return true; } private static int factorial(int i){ if (i <= 1) { return 1; } int p = 1; for (int j = 1; j <= i; j++) { p *= j; } return p; } public static String nThPermutation(List<String> in, int index){ if(in.size()==1) return in.get(0); int N = in.size(); int residue = index; int noOfPerm = factorial(N-1); int outputIndex = 0; if(noOfPerm<residue){ outputIndex = residue/noOfPerm; if(residue%noOfPerm==0){ outputIndex--; } residue = residue -(outputIndex * noOfPerm); } String indexDigit = in.get(outputIndex); in.remove(outputIndex); return indexDigit + nThPermutation(in, residue); } public static void main(String[] args) { String[] in1={"a","b","c"}; List<String> inp = new ArrayList<String>(Arrays.asList(in1)); System.out.println("Nth permutation elem:\n"+nThPermutation(inp,5)); System.out.println("\n--------------------------"); int[] in2 = {2,4,7,9,3,1}; nextPermutation(in2); System.out.println("next permutation element:"); for(int ch:in2) System.out.print(ch); System.out.println("\n--------------------------"); /** Generate all permutations in lex order **/ while(nextPermutation(in2)){ System.out.println(); for(int ch:in2) System.out.print(ch); } } }