problemmediumalgorithmspermutations-ii-problempermutations ii problempermutationsiiproblemleetcode-47leetcode 47leetcode47

Permutations of Array 2 - Array has duplicates

MediumUpdated: Sep 29, 2025
Practice on:

Problem

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

Examples

Example 1

Input: nums = [3,2,3]
Output: 3

Example 1:

Input: nums = [1,1,2]
Output:
[[1,1,2],
 [1,2,1],
 [2,1,1]]

Example 2:

Input: nums = [1,2,3]
Output:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

Solution

Method 1 - Backtracking with frequency map

This is similar to [Permutations of Array 1](permutations-of-array-1). But the normal decision tree will not work.

permutations-of-arr-2-wrong-way-sst.excalidraw

So, instead of array, we can use hashmap of frequency. This is our frequency map:

freq<num,count> = {1: 1, 2:1}

Now, decision tree will have 2 keys - [1, 2]. On the left side, we choose one 1 and one 2.

Final decision tree:

permutations-of-arr-2-sst.excalidraw.excalidraw

Code

Java
public List<List<Integer>> permuteUnique(int[] nums) {
	List<List<Integer>> ans = new ArrayList<>();
	List<Integer> subAns = new ArrayList<>();
	// frequency map
	Map<Integer, Long> countMap = Arrays.stream(nums).boxed().
                collect(Collectors.groupingBy(Integer::intValue, Collectors.counting()));

	dfs(nums.length, countMap, subAns, ans);
	return ans;
}

public void dfs(int numsLength, Map<Integer, Long> countMap, List<Integer> subAns, List<List<Integer>> ans) {
	if (subAns.size() == numsLength) {
		ans.add(new ArrayList<>(subAns));
		return;
	}
	for(int num: countMap.keySet()){
		if(countMap.get(num) > 0){
			subAns.add(num);
			countMap.put(num, countMap.get(num)-1);

			dfs(numsLength, countMap, subAns, ans);

			// undo
			countMap.put(num, countMap.get(num)+1);
			subAns.remove(subAns.size()-1);
		}
	}
}

Complexity

  • ⏰ Time complexity: O(n*2^n)
  • 🧺 Space complexity: O(n) assuming recursion stack

Method 2 - Backtracking with visited array and sorting

Code

Java
public List<List<Integer>> permuteUnique(int[] nums) {
	List<List<Integer>> list = new ArrayList<>();
	Arrays.sort(nums);
	backtrack(list, new ArrayList<>(), nums, new boolean[nums.length]);
	return list;
}

private void backtrack(List<List<Integer>> list, List<Integer> tempList, int[] nums, boolean[] used) {
	if (tempList.size() == nums.length) {
		list.add(new ArrayList<>(tempList));
		return;
	}
	for (int i = 0; i<nums.length; i++) {
		if (used[i] || i > 0 && nums[i] == nums[i - 1] && !used[i - 1]) {
			continue;
		}
		used[i] = true;
		tempList.add(nums[i]);
		backtrack(list, tempList, nums, used);
		used[i] = false;
		tempList.remove(tempList.size() - 1);
	}

}

Comments