1. Standard Permutations with Hash Set Deduplication
Intuition
Use a boolean array used of size N to track which indices are currently in the path. When the path reaches length N, serialize or insert the path list into a Hash Set. Finally, convert the set back to a 2D list.
Algorithm
- Step 1: Generate all N! permutations including duplicates using standard permutation backtracking.
- Step 2: Store generated permutations in a Hash Set to filter out identical sequences.
- Step 3: Convert the unique set entries into the final result list.
- Step 4: Return result list.
#include <iostream>#include <vector>#include <set> class Solution {public: void backtrack(std::vector<int>& nums, std::vector<bool>& used, std::vector<int>& path, std::set<std::vector<int>>& uniquePerms) { if (path.size() == nums.size()) { uniquePerms.insert(path); return; } for (int i = 0; i < (int)nums.size(); i++) { if (used[i]) continue; used[i] = true; path.push_back(nums[i]); backtrack(nums, used, path, uniquePerms); path.pop_back(); used[i] = false; } } std::vector<std::vector<int>> permuteUnique(std::vector<int>& nums) { std::set<std::vector<int>> uniquePerms; std::vector<bool> used(nums.size(), false); std::vector<int> path; backtrack(nums, used, path, uniquePerms); return std::vector<std::vector<int>>(uniquePerms.begin(), uniquePerms.end()); }}; int main() { Solution solver; std::vector<int> nums = {1, 1, 2}; std::vector<std::vector<int>> res = solver.permuteUnique(nums); std::cout << "Brute Force Output:\n"; for (const auto& p : res) { std::cout << "[ "; for (int x : p) std::cout << x << " "; std::cout << "]\n"; } return 0;}Time & Space Complexity
- Time complexity:
O(N! * N)— Generates all N! permutations and copies each vector of length N into the set. - Space complexity:
O(N! * N)— The Hash Set stores up to N! permutations of size N.