To generate all unique permutations of a given array (which may contain
duplicates), we use backtracking.
First, we
sort the array
to group
duplicates together. During the backtracking process, we
skip duplicate elements
to avoid
redundant permutations
.
This ensures that we generate all unique permutations efficiently.
class Solution { public: void backTrack(vector<vector<int>> &ans, vector<int> &tmp, vector<int> nums, vector<bool> &used){ if(tmp.size()==nums.size()){ ans.push_back(tmp); return; } for(int i=0;i<nums.size();i++){ // Condition to avoid duplicates // If element is already is used then continue OR // If current Element == Previous Element and Previous Element is not included that means the // permutation // which is going to build now will be same as permutations build by previous element. Hence, // it will create duplicates. if(used[i]==true || (i>0 && nums[i]==nums[i-1] && used[i-1]==false)) continue; used[i] = true; tmp.push_back(nums[i]); backTrack(ans,tmp,nums,used); tmp.pop_back(); used[i] = false; } } vector<vector<int>> permuteUnique(vector<int>& nums) { int n = nums.size(); vector<vector<int>> ans; vector<int> tmp; sort(nums.begin(),nums.end()); vector<bool> used(n,false); backTrack(ans,tmp,nums,used); return ans; } };
The algorithm generates all unique permutations of the input array, resulting in n!
permutations in
the worst case, and each permutation
takes
O(n)
time to
construct, where 'n'
is the size of the input.
The recursion stack depth is proportional to the size of the input('n'
), and the
temporary
vector stores intermediate results.