Daily Dose of DSA - Day 16
Generate all Permutations using Recursive method (TC : O(n!) SC : O(n * n!)) & using Iterative method (TC: O(n * n!) SC: O(n * n!))
Table of contents
Question Link : https://leetcode.com/problems/permutations/description/
Recursive Method:
The permutations
function is a recursive helper function that generates permutations. It takes three parameters: id
to keep track of the current index, v
which represents the vector containing the current permutation, and s
which is a set to store unique permutations.
Here's a step-by-step breakdown of the code:
The
permutations
function starts by calculating the size of the vectorv
and checks ifid
is greater than or equal ton
(the size ofv
). Ifid
is greater than or equal ton
, it means all elements have been fixed in their positions, and we have a complete permutation. In this case, the current permutationv
is inserted into the sets
to store unique permutations, and the function returns.If
id
is less thann
, the function enters a loop starting fromj = id
ton - 1
. This loop iterates over the remaining elements of the vector, considering each element as the first element in the permutation.Within the loop, the elements at indices
j
andid
are swapped using theswap
function. This swaps the current element with the element atid
, fixing it in its position for the current permutation.The
permutations
function is recursively called withid + 1
to generate permutations for the remaining elements. This recursive call handles the generation of all possible permutations by fixing the current element and recursively permuting the remaining elements.After the recursive call, the swapped elements are restored to their original positions by swapping
v[j]
andv[id]
again. This is necessary to backtrack and explore other possibilities for permutations.The loop continues, considering the next element as the first element and repeating the process to generate all permutations.
Once the loop completes, the
permutations
function ends, and we have generated all unique permutations ofnums
using recursion.The
permute
function serves as a wrapper function that initializes the vectorv
and the sets
. It calls thepermutations
function with an initialid
of 0 to start generating permutations. After generating all permutations, the unique permutations stored in the sets
are copied to a vectorv
and returned as the final result.
In summary, the code recursively generates all possible permutations of a given vector nums
by swapping elements and backtracking. The use of a set ensures that only unique permutations are stored. The final result is a vector of all unique permutations.
class Solution {
public:
void permutations(int id,vector<int> &v ,set<vector<int>> &s)
{
int n = (int)v.size();
if(id>=n)
{
s.insert(v);
return ;
}
for(int j = id ; j<=n-1;j++)
{
swap(v[j],v[id]);
permutations(id+1,v,s);
swap(v[j],v[id]); //backtrack
}
return ;
}
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> v;
set<vector<int>> s;
permutations(0,nums,s);
for(auto it:s)
{
v.push_back(it);
}
return v;
}
};
The space complexity of the set s
used to store permutations is indeed O(n * n!).
In the worst case, there can be n! permutations of the input vector nums
, and each permutation has a length of n. Storing all these permutations in the set s
will require O(n * n!) space.
Therefore, the correct space complexity of the provided code is O(n * n!) due to the space required to store the permutations in the set s
.
Iterative Method:
In this iterative solution, we start with the initial permutation and then generate new permutations by inserting the next number at different positions in each existing permutation. We iterate through all possible positions to split the vector and generate new permutations accordingly. The process continues until all possible permutations are generated.
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> result;
result.push_back(nums); // Initial permutation
int n = nums.size();
// Iterate through all possible positions to split the vector
for (int i = 0; i < n - 1; i++) {
int size = result.size();
// Generate new permutations by inserting the next number at different positions
for (int j = 0; j < size; j++) {
for (int k = i + 1; k < n; k++) {
vector<int> perm = result[j];
swap(perm[i], perm[k]);
result.push_back(perm);
}
}
}
return result;
}
};
The time complexity of the above iterative solution is O(n * n!), where n is the length of the input vector. This is because there are n! permutations of a vector of size n, and for each permutation, we iterate through n-1 positions to generate new permutations.
The space complexity of the above method is O(n n!), as we need to store all the generated permutations in the result vector*.* Since there are n! permutations and each permutation has n elements, the total space required is proportional to n n!.