1. Problem Statement (Simple Explanation):
You’re given an array nums that may contain duplicates.
You must return all unique permutations of nums.
The order of permutations in the output does not matter.
2. Examples:
Example 1:
Input: nums = [1,1,2]
All permutations (with duplicates):
[1,1,2]
[1,2,1]
[1,1,2] (duplicate)
[1,2,1] (duplicate)
[2,1,1]
[2,1,1] (duplicate)
Unique permutations:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
Example 2:
Input: nums = [1,2,3]
All permutations are unique:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
3. Approach – Backtracking with Duplicate Handling:
This is similar to Problem 46 (Permutations) but nums may contain duplicates, so naive permutation will produce duplicate lists. We need to avoid generating duplicates instead of removing them afterwards.
Standard trick: sort + skip equal values at same depth:
Steps:
Sort the array nums.
Then duplicates are adjacent.Use backtracking with:
current – current permutation being built.
used[i] – whether nums[i] is already in current at this point.
At each depth, when iterating indices i from 0 to n-1:
Skip if used[i] is already true (value already in permutation).
To avoid duplicates:
If i > 0 and nums[i] == nums[i-1] and used[i-1] == false,
skip i.
Why?
For duplicates (e.g., nums = [1a, 1b, 2] after sorting [1,1,2]):
At a given depth, we only allow the first unused duplicate to be chosen.
If nums[i] == nums[i-1] and we did not use the previous one at this level, using nums[i] instead would produce permutations we already generated with nums[i-1].
When current size equals nums.length, we have a full permutation; add a copy to the result.
Pseudo-code:
Let n = len(nums) (≤ 8):
In worst case (distinct numbers), we have n! permutations.
Time: O(n·n!) (building each permutation).
Space: O(n) extra for use and recursion (excluding output).
For n <= 8, 8! = 40320 → absolutely fine.
4. Java code:
6. C++ code:
7. Python code:
8. JavaScript code:






Comments
Post a Comment