82

For example I have this array:

int a[] = new int[]{3,4,6,2,1};

I need list of all permutations such that if one is like this, {3,2,1,4,6}, others must not be the same. I know that if the length of the array is n then there are n! possible combinations. How can this algorithm be written?

Update: thanks, but I need a pseudo code algorithm like:

for(int i=0;i<a.length;i++){
 // code here
}

Just algorithm. Yes, API functions are good, but it does not help me too much.

mkj
2,8515 gold badges25 silver badges28 bronze badges
asked May 27, 2010 at 10:32
3
  • 9
    There aren't 2^n possible combinations. There are n! permutations. Plus, I don't understand the question. Are you simply trying to exclude a single permutation, {3,2,1,4,6}? Commented May 27, 2010 at 10:34
  • yes sorry n! no all permutation should be unique Commented May 27, 2010 at 10:36
  • 1
    Could other language tags be added to this? Since this is an algorithm, it would be good to have multiple implementations in various languages. Commented Mar 1, 2016 at 15:07

14 Answers 14

162

Here is how you can print all permutations in 10 lines of code:

public class Permute{
 static void permute(java.util.List<Integer> arr, int k){
 for(int i = k; i < arr.size(); i++){
 java.util.Collections.swap(arr, i, k);
 permute(arr, k+1);
 java.util.Collections.swap(arr, k, i);
 }
 if (k == arr.size() -1){
 System.out.println(java.util.Arrays.toString(arr.toArray()));
 }
 }
 public static void main(String[] args){
 Permute.permute(java.util.Arrays.asList(3,4,6,2,1), 0);
 }
}

You take first element of an array (k=0) and exchange it with any element (i) of the array. Then you recursively apply permutation on array starting with second element. This way you get all permutations starting with i-th element. The tricky part is that after recursive call you must swap i-th element with first element back, otherwise you could get repeated values at the first spot. By swapping it back we restore order of elements (basically you do backtracking).

Iterators and Extension to the case of repeated values

The drawback of previous algorithm is that it is recursive, and does not play nicely with iterators. Another issue is that if you allow repeated elements in your input, then it won't work as is.

For example, given input [3,3,4,4] all possible permutations (without repetitions) are

[3, 3, 4, 4]
[3, 4, 3, 4]
[3, 4, 4, 3]
[4, 3, 3, 4]
[4, 3, 4, 3]
[4, 4, 3, 3]

(if you simply apply permute function from above you will get [3,3,4,4] four times, and this is not what you naturally want to see in this case; and the number of such permutations is 4!/(2!*2!)=6)

It is possible to modify the above algorithm to handle this case, but it won't look nice. Luckily, there is a better algorithm (I found it here) which handles repeated values and is not recursive.

First note, that permutation of array of any objects can be reduced to permutations of integers by enumerating them in any order.

To get permutations of an integer array, you start with an array sorted in ascending order. You 'goal' is to make it descending. To generate next permutation you are trying to find the first index from the bottom where sequence fails to be descending, and improves value in that index while switching order of the rest of the tail from descending to ascending in this case.

Here is the core of the algorithm:

//ind is an array of integers
for(int tail = ind.length - 1;tail > 0;tail--){
 if (ind[tail - 1] < ind[tail]){//still increasing
 //find last element which does not exceed ind[tail-1]
 int s = ind.length - 1;
 while(ind[tail-1] >= ind[s])
 s--;
 swap(ind, tail-1, s);
 //reverse order of elements in the tail
 for(int i = tail, j = ind.length - 1; i < j; i++, j--){
 swap(ind, i, j);
 }
 break;
 }
}

Here is the full code of iterator. Constructor accepts an array of objects, and maps them into an array of integers using HashMap.

import java.lang.reflect.Array;
import java.util.*;
class Permutations<E> implements Iterator<E[]>{
 private E[] arr;
 private int[] ind;
 private boolean has_next;
 public E[] output;//next() returns this array, make it public
 Permutations(E[] arr){
 this.arr = arr.clone();
 ind = new int[arr.length];
 //convert an array of any elements into array of integers - first occurrence is used to enumerate
 Map<E, Integer> hm = new HashMap<E, Integer>();
 for(int i = 0; i < arr.length; i++){
 Integer n = hm.get(arr[i]);
 if (n == null){
 hm.put(arr[i], i);
 n = i;
 }
 ind[i] = n.intValue();
 }
 Arrays.sort(ind);//start with ascending sequence of integers
 //output = new E[arr.length]; <-- cannot do in Java with generics, so use reflection
 output = (E[]) Array.newInstance(arr.getClass().getComponentType(), arr.length);
 has_next = true;
 }
 public boolean hasNext() {
 return has_next;
 }
 /**
 * Computes next permutations. Same array instance is returned every time!
 * @return
 */
 public E[] next() {
 if (!has_next)
 throw new NoSuchElementException();
 for(int i = 0; i < ind.length; i++){
 output[i] = arr[ind[i]];
 }
 //get next permutation
 has_next = false;
 for(int tail = ind.length - 1;tail > 0;tail--){
 if (ind[tail - 1] < ind[tail]){//still increasing
 //find last element which does not exceed ind[tail-1]
 int s = ind.length - 1;
 while(ind[tail-1] >= ind[s])
 s--;
 swap(ind, tail-1, s);
 //reverse order of elements in the tail
 for(int i = tail, j = ind.length - 1; i < j; i++, j--){
 swap(ind, i, j);
 }
 has_next = true;
 break;
 }
 }
 return output;
 }
 private void swap(int[] arr, int i, int j){
 int t = arr[i];
 arr[i] = arr[j];
 arr[j] = t;
 }
 public void remove() {
 }
}

Usage/test:

 TCMath.Permutations<Integer> perm = new TCMath.Permutations<Integer>(new Integer[]{3,3,4,4,4,5,5});
 int count = 0;
 while(perm.hasNext()){
 System.out.println(Arrays.toString(perm.next()));
 count++;
 }
 System.out.println("total: " + count);

Prints out all 7!/(2!*3!*2!)=210 permutations.

Hengameh
9127 silver badges12 bronze badges
answered Jan 21, 2013 at 17:27
5
  • 1
    Great Answer. Can you please explain why it's 4!/(2!2!)=6 and not 4!/(2!)=12 Commented Jul 7, 2013 at 22:06
  • 2
    First of all, I know that answer is 6 (from my [3,3,4,4] example). To derive the formula, think about [3,3,4,4] as two blue and two red balls. The question is how many ways to position balls (balls of the same color are the same). If you somehow position your balls, then interchanging of the blue balls (2! ways of doing that) or two red balls (2! ways of doing that) does not change anything. Now, we have 4! ways to place 4 balls, but permuting blue balls (2! ways) or red balls (2! ways) does not change positioning of the balls. So you get 4!/(2!*2!) as final answer Commented Jul 10, 2013 at 1:16
  • 1
    Time complexity of first algorithm is O(n*n!), is that right? Commented Aug 17, 2015 at 1:59
  • this is the fastest permutation algorithm i've tried. good job Commented Apr 17, 2016 at 2:06
  • I rarely like long explanations on SO, but this is an awesome exception. Thanks for explaining! Commented Apr 24, 2019 at 14:35
28

If you're using C++, you can use std::next_permutation from the <algorithm> header file:

int a[] = {3,4,6,2,1};
int size = sizeof(a)/sizeof(a[0]);
std::sort(a, a+size);
do {
 // print a's elements
} while(std::next_permutation(a, a+size));
Walter
45.8k23 gold badges118 silver badges207 bronze badges
answered May 27, 2010 at 10:39
18

Here is an implementation of the Permutation in Java:

Permutation - Java

You should have a check on it!

Edit: code pasted below to protect against link-death:

// Permute.java -- A class generating all permutations
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.lang.reflect.Array;
public class Permute implements Iterator {
 private final int size;
 private final Object [] elements; // copy of original 0 .. size-1
 private final Object ar; // array for output, 0 .. size-1
 private final int [] permutation; // perm of nums 1..size, perm[0]=0
 private boolean next = true;
 // int[], double[] array won't work :-(
 public Permute (Object [] e) {
 size = e.length;
 elements = new Object [size]; // not suitable for primitives
 System.arraycopy (e, 0, elements, 0, size);
 ar = Array.newInstance (e.getClass().getComponentType(), size);
 System.arraycopy (e, 0, ar, 0, size);
 permutation = new int [size+1];
 for (int i=0; i<size+1; i++) {
 permutation [i]=i;
 }
 }
 private void formNextPermutation () {
 for (int i=0; i<size; i++) {
 // i+1 because perm[0] always = 0
 // perm[]-1 because the numbers 1..size are being permuted
 Array.set (ar, i, elements[permutation[i+1]-1]);
 }
 }
 public boolean hasNext() {
 return next;
 }
 public void remove() throws UnsupportedOperationException {
 throw new UnsupportedOperationException();
 }
 private void swap (final int i, final int j) {
 final int x = permutation[i];
 permutation[i] = permutation [j];
 permutation[j] = x;
 }
 // does not throw NoSuchElement; it wraps around!
 public Object next() throws NoSuchElementException {
 formNextPermutation (); // copy original elements
 int i = size-1;
 while (permutation[i]>permutation[i+1]) i--;
 if (i==0) {
 next = false;
 for (int j=0; j<size+1; j++) {
 permutation [j]=j;
 }
 return ar;
 }
 int j = size;
 while (permutation[i]>permutation[j]) j--;
 swap (i,j);
 int r = size;
 int s = i+1;
 while (r>s) { swap(r,s); r--; s++; }
 return ar;
 }
 public String toString () {
 final int n = Array.getLength(ar);
 final StringBuffer sb = new StringBuffer ("[");
 for (int j=0; j<n; j++) {
 sb.append (Array.get(ar,j).toString());
 if (j<n-1) sb.append (",");
 }
 sb.append("]");
 return new String (sb);
 }
 public static void main (String [] args) {
 for (Iterator i = new Permute(args); i.hasNext(); ) {
 final String [] a = (String []) i.next();
 System.out.println (i);
 }
 }
}
Vala
5,6941 gold badge32 silver badges56 bronze badges
answered May 27, 2010 at 10:40
4
  • 5
    +1 please add the relevant code to your post though, in case the link ever goes down Commented May 27, 2010 at 20:30
  • Thanks also for eliminating the line numbers. :P Commented Sep 24, 2015 at 1:30
  • And the link went down. :) Commented Dec 29, 2021 at 18:51
  • @BlueRaja-DannyPflughoeft Nice catch, the link did go down Commented Feb 28, 2022 at 16:12
7

According to wiki https://en.wikipedia.org/wiki/Heap%27s_algorithm

Heap's algorithm generates all possible permutations of n objects. It was first proposed by B. R. Heap in 1963. The algorithm minimizes movement: it generates each permutation from the previous one by interchanging a single pair of elements; the other n−2 elements are not disturbed. In a 1977 review of permutation-generating algorithms, Robert Sedgewick concluded that it was at that time the most effective algorithm for generating permutations by computer.

So if we want to do it in recursive manner, Sudo code is bellow.

procedure generate(n : integer, A : array of any):
 if n = 1 then
 output(A)
 else
 for i := 0; i < n - 1; i += 1 do
 generate(n - 1, A)
 if n is even then
 swap(A[i], A[n-1])
 else
 swap(A[0], A[n-1])
 end if
 end for
 generate(n - 1, A)
 end if

java code:

public static void printAllPermutations(
 int n, int[] elements, char delimiter) {
 if (n == 1) {
 printArray(elements, delimiter);
 } else {
 for (int i = 0; i < n - 1; i++) {
 printAllPermutations(n - 1, elements, delimiter);
 if (n % 2 == 0) {
 swap(elements, i, n - 1);
 } else {
 swap(elements, 0, n - 1);
 }
 }
 printAllPermutations(n - 1, elements, delimiter);
 }
}
private static void printArray(int[] input, char delimiter) {
 int i = 0;
 for (; i < input.length; i++) {
 System.out.print(input[i]);
 }
 System.out.print(delimiter);
}
private static void swap(int[] input, int a, int b) {
 int tmp = input[a];
 input[a] = input[b];
 input[b] = tmp;
}
public static void main(String[] args) {
 int[] input = new int[]{0,1,2,3};
 printAllPermutations(input.length, input, ',');
}
answered Jan 20, 2019 at 6:39
5

This a 2-permutation for a list wrapped in an iterator

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/* all permutations of two objects 
 * 
 * for ABC: AB AC BA BC CA CB
 * 
 * */
public class ListPermutation<T> implements Iterator {
 int index = 0;
 int current = 0;
 List<T> list;
 public ListPermutation(List<T> e) {
 list = e;
 }
 public boolean hasNext() {
 return !(index == list.size() - 1 && current == list.size() - 1);
 }
 public List<T> next() {
 if(current == index) {
 current++;
 }
 if (current == list.size()) {
 current = 0;
 index++;
 }
 List<T> output = new LinkedList<T>();
 output.add(list.get(index));
 output.add(list.get(current));
 current++;
 return output;
 }
 public void remove() {
 }
}
answered Sep 29, 2012 at 1:06
5

There are n! total permutations for the given array size n. Here is code written in Java using DFS.

public List<List<Integer>> permute(int[] nums) {
 List<List<Integer>> results = new ArrayList<List<Integer>>();
 if (nums == null || nums.length == 0) {
 return results;
 }
 List<Integer> result = new ArrayList<>();
 dfs(nums, results, result);
 return results;
}
public void dfs(int[] nums, List<List<Integer>> results, List<Integer> result) {
 if (nums.length == result.size()) {
 List<Integer> temp = new ArrayList<>(result);
 results.add(temp);
 } 
 for (int i=0; i<nums.length; i++) {
 if (!result.contains(nums[i])) {
 result.add(nums[i]);
 dfs(nums, results, result);
 result.remove(result.size() - 1);
 }
 }
}

For input array [3,2,1,4,6], there are totally 5! = 120 possible permutations which are:

[[3,4,6,2,1],[3,4,6,1,2],[3,4,2,6,1],[3,4,2,1,6],[3,4,1,6,2],[3,4,1,2,6],[3,6,4,2,1],[3,6,4,1,2],[3,6,2,4,1],[3,6,2,1,4],[3,6,1,4,2],[3,6,1,2,4],[3,2,4,6,1],[3,2,4,1,6],[3,2,6,4,1],[3,2,6,1,4],[3,2,1,4,6],[3,2,1,6,4],[3,1,4,6,2],[3,1,4,2,6],[3,1,6,4,2],[3,1,6,2,4],[3,1,2,4,6],[3,1,2,6,4],[4,3,6,2,1],[4,3,6,1,2],[4,3,2,6,1],[4,3,2,1,6],[4,3,1,6,2],[4,3,1,2,6],[4,6,3,2,1],[4,6,3,1,2],[4,6,2,3,1],[4,6,2,1,3],[4,6,1,3,2],[4,6,1,2,3],[4,2,3,6,1],[4,2,3,1,6],[4,2,6,3,1],[4,2,6,1,3],[4,2,1,3,6],[4,2,1,6,3],[4,1,3,6,2],[4,1,3,2,6],[4,1,6,3,2],[4,1,6,2,3],[4,1,2,3,6],[4,1,2,6,3],[6,3,4,2,1],[6,3,4,1,2],[6,3,2,4,1],[6,3,2,1,4],[6,3,1,4,2],[6,3,1,2,4],[6,4,3,2,1],[6,4,3,1,2],[6,4,2,3,1],[6,4,2,1,3],[6,4,1,3,2],[6,4,1,2,3],[6,2,3,4,1],[6,2,3,1,4],[6,2,4,3,1],[6,2,4,1,3],[6,2,1,3,4],[6,2,1,4,3],[6,1,3,4,2],[6,1,3,2,4],[6,1,4,3,2],[6,1,4,2,3],[6,1,2,3,4],[6,1,2,4,3],[2,3,4,6,1],[2,3,4,1,6],[2,3,6,4,1],[2,3,6,1,4],[2,3,1,4,6],[2,3,1,6,4],[2,4,3,6,1],[2,4,3,1,6],[2,4,6,3,1],[2,4,6,1,3],[2,4,1,3,6],[2,4,1,6,3],[2,6,3,4,1],[2,6,3,1,4],[2,6,4,3,1],[2,6,4,1,3],[2,6,1,3,4],[2,6,1,4,3],[2,1,3,4,6],[2,1,3,6,4],[2,1,4,3,6],[2,1,4,6,3],[2,1,6,3,4],[2,1,6,4,3],[1,3,4,6,2],[1,3,4,2,6],[1,3,6,4,2],[1,3,6,2,4],[1,3,2,4,6],[1,3,2,6,4],[1,4,3,6,2],[1,4,3,2,6],[1,4,6,3,2],[1,4,6,2,3],[1,4,2,3,6],[1,4,2,6,3],[1,6,3,4,2],[1,6,3,2,4],[1,6,4,3,2],[1,6,4,2,3],[1,6,2,3,4],[1,6,2,4,3],[1,2,3,4,6],[1,2,3,6,4],[1,2,4,3,6],[1,2,4,6,3],[1,2,6,3,4],[1,2,6,4,3]]

Hope this helps.

MC Emperor
23.2k16 gold badges89 silver badges138 bronze badges
answered Mar 14, 2016 at 0:08
3

Example with primitive array:

public static void permute(int[] intArray, int start) {
 for(int i = start; i < intArray.length; i++){
 int temp = intArray[start];
 intArray[start] = intArray[i];
 intArray[i] = temp;
 permute(intArray, start + 1);
 intArray[i] = intArray[start];
 intArray[start] = temp;
 }
 if (start == intArray.length - 1) {
 System.out.println(java.util.Arrays.toString(intArray));
 }
}
public static void main(String[] args){
 int intArr[] = {1, 2, 3};
 permute(intArr, 0);
}
answered Aug 6, 2017 at 10:56
1

Here is one using arrays and Java 8+

import java.util.Arrays;
import java.util.stream.IntStream;
public class HelloWorld {
 public static void main(String[] args) {
 int[] arr = {1, 2, 3, 5};
 permutation(arr, new int[]{});
 }
 static void permutation(int[] arr, int[] prefix) {
 if (arr.length == 0) {
 System.out.println(Arrays.toString(prefix));
 }
 for (int i = 0; i < arr.length; i++) {
 int i2 = i;
 int[] pre = IntStream.concat(Arrays.stream(prefix), IntStream.of(arr[i])).toArray();
 int[] post = IntStream.range(0, arr.length).filter(i1 -> i1 != i2).map(v -> arr[v]).toArray();
 permutation(post, pre);
 }
 }
}
answered Dec 30, 2020 at 16:42
0

Visual representation of the 3-item recursive solution: http://www.docdroid.net/ea0s/generatepermutations.pdf.html

Breakdown:

  1. For a two-item array, there are two permutations:
    • The original array, and
    • The two elements swapped
  2. For a three-item array, there are six permutations:
    • The permutations of the bottom two elements, then
    • Swap 1st and 2nd items, and the permutations of the bottom two element
    • Swap 1st and 3rd items, and the permutations of the bottom two elements.
    • Essentially, each of the items gets its chance at the first slot
answered Jul 4, 2014 at 5:27
0

A simple java implementation, refer to c++ std::next_permutation:

public static void main(String[] args){
 int[] list = {1,2,3,4,5};
 List<List<Integer>> output = new Main().permute(list);
 for(List result: output){
 System.out.println(result);
 }
}
public List<List<Integer>> permute(int[] nums) {
 List<List<Integer>> list = new ArrayList<List<Integer>>();
 int size = factorial(nums.length);
 // add the original one to the list
 List<Integer> seq = new ArrayList<Integer>();
 for(int a:nums){
 seq.add(a);
 }
 list.add(seq);
 // generate the next and next permutation and add them to list
 for(int i = 0;i < size - 1;i++){
 seq = new ArrayList<Integer>();
 nextPermutation(nums);
 for(int a:nums){
 seq.add(a);
 }
 list.add(seq);
 }
 return list;
}
int factorial(int n){
 return (n==1)?1:n*factorial(n-1);
}
void nextPermutation(int[] nums){
 int i = nums.length -1; // start from the end
 while(i > 0 && nums[i-1] >= nums[i]){
 i--;
 }
 if(i==0){
 reverse(nums,0,nums.length -1 );
 }else{
 // found the first one not in order 
 int j = i;
 // found just bigger one
 while(j < nums.length && nums[j] > nums[i-1]){
 j++;
 }
 //swap(nums[i-1],nums[j-1]);
 int tmp = nums[i-1];
 nums[i-1] = nums[j-1];
 nums[j-1] = tmp;
 reverse(nums,i,nums.length-1); 
 }
}
// reverse the sequence
void reverse(int[] arr,int start, int end){
 int tmp;
 for(int i = 0; i <= (end - start)/2; i++ ){
 tmp = arr[start + i];
 arr[start + i] = arr[end - i];
 arr[end - i ] = tmp;
 }
}
answered Oct 21, 2016 at 12:27
0

Do like this...

import java.util.ArrayList;
import java.util.Arrays;
public class rohit {
 public static void main(String[] args) {
 ArrayList<Integer> a=new ArrayList<Integer>();
 ArrayList<Integer> b=new ArrayList<Integer>();
 b.add(1);
 b.add(2);
 b.add(3);
 permu(a,b);
 }
 public static void permu(ArrayList<Integer> prefix,ArrayList<Integer> value) {
 if(value.size()==0) {
 System.out.println(prefix);
 } else {
 for(int i=0;i<value.size();i++) {
 ArrayList<Integer> a=new ArrayList<Integer>();
 a.addAll(prefix);
 a.add(value.get(i));
 ArrayList<Integer> b=new ArrayList<Integer>();
 b.addAll(value.subList(0, i));
 b.addAll(value.subList(i+1, value.size()));
 permu(a,b);
 }
 }
 }
}
Ryan
1,9782 gold badges25 silver badges37 bronze badges
answered Feb 24, 2018 at 10:05
0

Implementation via recursion (dynamic programming), in Java, with test case (TestNG).


Code

PrintPermutation.java

import java.util.Arrays;
/**
 * Print permutation of n elements.
 * 
 * @author eric
 * @date Oct 13, 2018 12:28:10 PM
 */
public class PrintPermutation {
 /**
 * Print permutation of array elements.
 * 
 * @param arr
 * @return count of permutation,
 */
 public static int permutation(int arr[]) {
 return permutation(arr, 0);
 }
 /**
 * Print permutation of part of array elements.
 * 
 * @param arr
 * @param n
 * start index in array,
 * @return count of permutation,
 */
 private static int permutation(int arr[], int n) {
 int counter = 0;
 for (int i = n; i < arr.length; i++) {
 swapArrEle(arr, i, n);
 counter += permutation(arr, n + 1);
 swapArrEle(arr, n, i);
 }
 if (n == arr.length - 1) {
 counter++;
 System.out.println(Arrays.toString(arr));
 }
 return counter;
 }
 /**
 * swap 2 elements in array,
 * 
 * @param arr
 * @param i
 * @param k
 */
 private static void swapArrEle(int arr[], int i, int k) {
 int tmp = arr[i];
 arr[i] = arr[k];
 arr[k] = tmp;
 }
}

PrintPermutationTest.java (test case via TestNG)

import org.testng.Assert;
import org.testng.annotations.Test;
/**
 * PrintPermutation test.
 * 
 * @author eric
 * @date Oct 14, 2018 3:02:23 AM
 */
public class PrintPermutationTest {
 @Test
 public void test() {
 int arr[] = new int[] { 0, 1, 2, 3 };
 Assert.assertEquals(PrintPermutation.permutation(arr), 24);
 int arrSingle[] = new int[] { 0 };
 Assert.assertEquals(PrintPermutation.permutation(arrSingle), 1);
 int arrEmpty[] = new int[] {};
 Assert.assertEquals(PrintPermutation.permutation(arrEmpty), 0);
 }
}
answered Oct 13, 2018 at 19:25
0

Instead of permutations, we can preferably call them combinations.

Irrespective of the coding language, we can use a simple approach, To append the array elements to the already existing list of combinations thus, using the dynamic programming approach.

This code focuses on those combinations without adjacency as well.

#include <iostream>
#include <vector>
using namespace std;
template <class myIterator, class T>
myIterator findDigit(myIterator first, myIterator last, T val)
{
 while(first != last) {
 if(*first == val) { break; }
 first++;
 }
 return first;
}
void printCombinations(vector<vector<int>> combinations)
{
 cout << "printing all " << combinations.size() << " combinations" << endl;
 for(int i=0; i<combinations.size(); i++) {
 cout << "[";
 for(int j=0; j<combinations[i].size(); j++) {
 cout << " " << combinations[i][j] << " ";
 }
 cout << "] , ";
 }
 return;
}
int main()
{
 vector<int> a = {1,2,3,4,5};
 vector<vector<int>> comb;
 vector<int> t;
 int len=a.size();
 for(int i=0; i<len; i++) {
 t.push_back(a.at(i));
 comb.push_back(t);
 t.clear();
 }
 for(int l=1; l<len; l++) {
 for(int j=0; j<comb.size(); j++) {
 if(comb[j].size()==l) {
 int t = comb[j].back();
 if(t != a.back()) {
 vector<int>::iterator it = findDigit(a.begin(), a.end(), t);
 for(std::vector<int>::iterator k=it+1; k!=a.end();k++) {
 vector<int> t (comb[j].begin(), comb[j].end());
 t.push_back(*k);
 comb.push_back(t);
 t.clear();
 }
 }
 }
 }
 }
 printCombinations(comb);
 return 0;
}

Although the complexity is a bit high, it's definitely lower than the recursion approach, especially when the array size is very large.

Output for the above array (or vecter, if you will) is :

printing all 31 combinations
[ 1 ], [ 2 ], [ 3 ], [ 4 ], [ 5 ], [ 1 2 ], [ 1 3 ], [ 1 4 ], [ 1 5 ], [ 2 3 ], [ 2 4 ], [ 2 5 ], [ 3 4 ], [ 3 5 ], [ 4 5 ], [ 1 
 2 3 ], [ 1 2 4 ], [ 1 2 5 ], [ 1 3 4 ], [ 1 3 5 ], [ 1 4 5 ], [ 2 3 4 ], [ 2 3 5 ], [ 2 4 5 ], [ 3 4 5 ], [ 1 2 3 4 
], [ 1 2 3 5 ], [ 1 2 4 5 ], [ 1 3 4 5 ], [ 2 3 4 5 ], [ 1 2 3 4 5 ],

The code can be used for characters and strings as well, by just replacing the datatype wherever required.

eg.

vector<char> a = {'d','g','y','u','t'};

To give

printing all 31 combinations
[ d ] , [ g ] , [ y ] , [ u ] , [ t ] , [ d g ] , [ d y ] , [ d u ] , [ d t ] , [ g y ] , [ g u ] , [ g t ] , [ y u ] , [ y t ] , 
[ u t ] , [ d g y ] , [ d g u ] , [ d g t ] , [ d y u ] , [ d y t ] , [ d u t ] , [ g y u ] , [ g y t ] , [ g u t ] , [ 
y u t ] , [ d g y u ] , [ d g y t ] , [ d g u t ] , [ d y u t ] , [ g y u t ] , [ d g y u t ] ,

and

vector<string> a = {"asdf","myfl", "itshot", "holy"};

to give

printing all 15 combinations
[ asdf ] , [ myfl ] , [ itshot ] , [ holy ] , [ asdf myfl ] , [ asdf itshot ] , [ asdf holy ] , [ myfl itshot ] , [ myfl holy ] , [ itshot holy ] , [ asdf myfl itshot ] , [ asdf myfl holy ] , [ asdf itshot holy ] , [ myfl itshot holy ] , [ asdf myfl itshot holy ] ,
answered Oct 5, 2021 at 14:52
2
  • They asked for permutations of N out of N (how many unique ways can they be rearranged?) (Usually, this ignores equality checking, assuming all values are "unique"). You provided indeed combinations of 1..=N out of N, preserving order. Two completely different words, two completely different problems. Commented Nov 19, 2021 at 20:40
  • I don't think the question was asked quite clearly, and that you read the question carefully. It mentions "I know that if the length of the array is n then there are n! possible combinations. How can this algorithm be written?" My guess is that the behold questioner wanted one, got two. Commented Mar 31, 2023 at 5:49
0

Permutation via iteration, in go.

// find all permutation of []T, return [][]T, not ordered, via iteration,
// tips: for empty input, return 1 empty combination,
func FindAllPermutation[T any](ts []T) [][]T {
 combList := [][]T{{}} // when empty input, has 1 empty combination, not 0 combination,
 for i := len(ts) - 1; i >= 0; i-- {
 // prefix := ts[0:i]
 mover := ts[i]
 // fmt.Printf("\nprefix = %v, mover = %v:\n", prefix, mover)
 var combList2 [][]T // combinations with an extra item added,
 for _, comb := range combList {
 for j := 0; j <= len(comb); j++ { // insert mover at index j of comb,
 comb2 := append(append(append([]T{}, comb[0:j]...), mover), comb[j:]...) // new_empty + left + mover + right
 // fmt.Printf("\t%v\n", comb2)
 combList2 = append(combList2, comb2)
 }
 }
 combList = combList2
 }
 return combList
}
answered Mar 29, 2023 at 8:58

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.