LeetCode – Permutations II (Java)

Given a collection of numbers that might contain duplicates, return all possible unique permutations.

For example, [1,1,2] have the following unique permutations:
[1,1,2], [1,2,1], and [2,1,1].

Basic Idea

For each number in the array, swap it with every element after it. To avoid duplicate, we need to check the existing sequence first.

Java Solution 1

public ArrayList<ArrayList<Integer>> permuteUnique(int[] num) {
	ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
	permuteUnique(num, 0, result);
	return result;
}
 
private void permuteUnique(int[] num, int start, ArrayList<ArrayList<Integer>> result) {
 
	if (start >= num.length ) {
		ArrayList<Integer> item = convertArrayToList(num);
		result.add(item);
	}
 
	for (int j = start; j <= num.length-1; j++) {
		if (containsDuplicate(num, start, j)) {
			swap(num, start, j);
			permuteUnique(num, start + 1, result);
			swap(num, start, j);
		}
	}
}
 
private ArrayList<Integer> convertArrayToList(int[] num) {
	ArrayList<Integer> item = new ArrayList<Integer>();
	for (int h = 0; h < num.length; h++) {
		item.add(num[h]);
	}
	return item;
}
 
private boolean containsDuplicate(int[] arr, int start, int end) {
	for (int i = start; i <= end-1; i++) {
		if (arr[i] == arr[end]) {
			return false;
		}
	}
	return true;
}
 
private void swap(int[] a, int i, int j) {
	int temp = a[i];
	a[i] = a[j];
	a[j] = temp;
}

Java Solution 2

Use set to maintain uniqueness:

public static ArrayList<ArrayList<Integer>> permuteUnique(int[] num) {
	ArrayList<ArrayList<Integer>> returnList = new ArrayList<ArrayList<Integer>>();
	returnList.add(new ArrayList<Integer>());
 
	for (int i = 0; i < num.length; i++) {
		Set<ArrayList<Integer>> currentSet = new HashSet<ArrayList<Integer>>();
		for (List<Integer> l : returnList) {
			for (int j = 0; j < l.size() + 1; j++) {
				l.add(j, num[i]);
				ArrayList<Integer> T = new ArrayList<Integer>(l);
				l.remove(j);
				currentSet.add(T);
			}
		}
		returnList = new ArrayList<ArrayList<Integer>>(currentSet);
	}
 
	return returnList;
}

Thanks to Milan for such a simple solution!

Category >> Algorithms  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>
  • Cole Thatcher

    Will take O(n!) space?

  • Paul

    thanks for the solution. Would you mind to explain the containsDuplicate code?

    private boolean containsDuplicate(int[] arr, int start, int end) {
    for (int i = start; i <= end-1; i++) {
    if (arr[i] == arr[end]) {
    return false;
    }
    }
    return true;
    }

    Why should we do that to avoid duplication.

  • vj

    You can swap the input and skip numbers that are duplicates.

    import java.util.*;

    public class PrintUniquePermutations {

    public static void main(String args[]) {

    int[] input = {1, 2, 1};

    Arrays.sort(input);

    String prefix = “”;

    printUnique(prefix, input, 0);

    }

    private static void printUnique(String prefix, int[] input, int start) {

    if (start == input.length) {

    System.out.println(prefix);

    return;

    }

    for (int i = start; i < input.length; i++) {

    if (i != start && input[i] == input[i-1]) {

    continue;

    }

    swap(input, i, start);

    printUnique(prefix + ", " + String.valueOf(input[start]), input, start + 1);

    swap(input, i, start);

    }

    }

    private static void swap(int[] input, int i, int j) {

    int tmp = input[i];

    input[i] = input[j];

    input[j] = tmp;

    }

    }

  • ryanlr

    Thanks! Great solution!

  • Milan

    Use set to maintain uniqueness:

    List<List> returnList = new ArrayList<List> ();

    returnList.add(new ArrayList());

    for (int i=0 ; i < num.length; i++){

    Set<List> currnetSet = new HashSet<List> ();

    for (List l:returnList){

    for(int j=0;j< l.size() +1;j++){

    l.add(j,num[i]);

    ArrayList T = new ArrayList(l);

    l.remove(j);

    currnetSet.add(T);

    }

    }

    returnList = new ArrayList<List> (currnetSet);

    }

    return returnList;

    }

  • SSSSS

    应该是不contain duplicate