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].

Java Solution 1

Based on Permutation, we can add a set to track if an element is duplicate and no need to swap.

public List<List<Integer>> permuteUnique(int[] nums) {
    List<List<Integer>> result = new ArrayList<>();
    helper(0, nums, result);
    return result;
}
 
private void helper(int start, int[] nums, List<List<Integer>> result){
    if(start==nums.length-1){
        ArrayList<Integer> list = new ArrayList<>();
        for(int num: nums){
            list.add(num);
        }
        result.add(list);
        return;
    }
 
    HashSet<Integer> set = new HashSet<>();
 
    for(int i=start; i<nums.length; i++){
        if(set.contains(nums[i])){
            continue;
        }
        set.add(nums[i]);
 
        swap(nums, i, start);
        helper(start+1, nums, result);
        swap(nums, i, start);
    }
}
 
private void swap(int[] nums, int i, int j){
    int temp = nums[i];
    nums[i] = nums[j];
    nums[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!

10 thoughts on “LeetCode – Permutations II (Java)”

  1. if(set.contains(nums[i])){
    =====
    not sure using set. what for?

    basically you just need skip from forming similar string
    lets say string 1xx 1 xxx 1 xxx , if you swap 1 and 1, you will make 2 same strings

    so as soon as i-index and start-index same symbol, just skip next swap operation

  2. 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.

  3. 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;

    }

    }

  4. 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;

    }

Leave a Comment