Skip to content

Commit 2a2b448

Browse files
committed
Create 0046-Permutations.md
1 parent 4f16aa4 commit 2a2b448

File tree

1 file changed

+215
-0
lines changed

1 file changed

+215
-0
lines changed
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
---
2+
id: permutations
3+
title: Permutations(LeetCode)
4+
sidebar_label: 0046-Permutations
5+
tags:
6+
- Array
7+
- Backtracking
8+
description: Given an array `nums` of distinct integers, return all the possible permutations. You can return the answer in any order.
9+
10+
sidebar_position: 46
11+
---
12+
13+
## Problem Statement
14+
15+
Given an array `nums` of distinct integers, return all the possible permutations. You can return the answer in any order.
16+
17+
### Examples
18+
19+
**Example 1:**
20+
21+
```plaintext
22+
Input: nums = [1,2,3]
23+
Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
24+
```
25+
26+
**Example 2:**
27+
28+
```plaintext
29+
Input: nums = [0,1]
30+
Output: [[0,1],[1,0]]
31+
```
32+
33+
**Example 3:**
34+
35+
```plaintext
36+
Input: nums = [1]
37+
Output: [[1]]
38+
```
39+
40+
### Constraints:
41+
42+
- `1 <= nums.length <= 6`
43+
- `10 <= nums[i] <= 10`
44+
- All the integers of `nums` are unique.
45+
46+
## Solution
47+
48+
In this problem, we aim to find all the possible permutations from an array of distinct integers. We explore two main approaches: Recursive approach and Backtracking approach.
49+
50+
### Approach 1: Recursive
51+
We have given the nums array, so we will declare an ans vector of vector that will store all the permutations also declare a data structure.
52+
53+
Declare a map and initialize it to zero and call the recursive function
54+
55+
Base condition :
56+
57+
When the data structure's size is equal to n(size of nums array) then it is a permutation and stores that permutation in our ans, then returns it.
58+
59+
Recursion:
60+
61+
Run a for loop starting from 0 to nums.size() - 1. Check if the frequency of i is unmarked, if it is unmarked then it means it has not been picked and then we pick. And make sure it is marked as picked.
62+
63+
Call the recursion with the parameters to pick the other elements when we come back from the recursion make sure you throw that element out. And unmark that element in the map.
64+
65+
#### Implementation
66+
67+
```C++
68+
class Solution {
69+
private:
70+
void recurPermute(vector < int > & ds, vector < int > & nums, vector < vector < int >> & ans, int freq[]) {
71+
if (ds.size() == nums.size()) {
72+
ans.push_back(ds);
73+
return;
74+
}
75+
for (int i = 0; i < nums.size(); i++) {
76+
if (!freq[i]) {
77+
ds.push_back(nums[i]);
78+
freq[i] = 1;
79+
recurPermute(ds, nums, ans, freq);
80+
freq[i] = 0;
81+
ds.pop_back();
82+
}
83+
}
84+
}
85+
public:
86+
vector < vector < int >> permute(vector < int > & nums) {
87+
vector < vector < int >> ans;
88+
vector < int > ds;
89+
int freq[nums.size()];
90+
for (int i = 0; i < nums.size(); i++) freq[i] = 0;
91+
recurPermute(ds, nums, ans, freq);
92+
return ans;
93+
}
94+
};
95+
```
96+
97+
```Java
98+
class Solution {
99+
private void recurPermute(int index, int[] nums, List < List < Integer >> ans) {
100+
if (index == nums.length) {
101+
// copy the ds to ans
102+
List < Integer > ds = new ArrayList < > ();
103+
for (int i = 0; i < nums.length; i++) {
104+
ds.add(nums[i]);
105+
}
106+
ans.add(new ArrayList < > (ds));
107+
return;
108+
}
109+
for (int i = index; i < nums.length; i++) {
110+
swap(i, index, nums);
111+
recurPermute(index + 1, nums, ans);
112+
swap(i, index, nums);
113+
}
114+
}
115+
private void swap(int i, int j, int[] nums) {
116+
int t = nums[i];
117+
nums[i] = nums[j];
118+
nums[j] = t;
119+
}
120+
public List < List < Integer >> permute(int[] nums) {
121+
List < List < Integer >> ans = new ArrayList < > ();
122+
recurPermute(0, nums, ans);
123+
return ans;
124+
}
125+
};
126+
```
127+
128+
### Complexity Analysis
129+
130+
- **Time complexity**: N! x N
131+
- **Space complexity**: O(N)
132+
133+
### Approach 2: With Backtracking
134+
135+
We have given the nums array, so we will declare an ans vector of vector that will store all the permutations.
136+
137+
Call a recursive function that starts with zero, nums array, and ans vector.
138+
139+
Declare a map and initialize it to zero and call the recursive function
140+
141+
Base condition:
142+
143+
Whenever the index reaches the end take the nums array and put it in ans vector and return.
144+
145+
Recursion:
146+
147+
Go from index to n - 1 and swap once the swap has been done call recursion for the next state. After coming back from the recursion make sure you re-swap it because, for the next element, the swap will not take place.
148+
149+
#### Implementation
150+
151+
```C++
152+
class Solution {
153+
private:
154+
void recurPermute(int index, vector < int > & nums, vector < vector < int >> & ans) {
155+
if (index == nums.size()) {
156+
ans.push_back(nums);
157+
return;
158+
}
159+
for (int i = index; i < nums.size(); i++) {
160+
swap(nums[index], nums[i]);
161+
recurPermute(index + 1, nums, ans);
162+
swap(nums[index], nums[i]);
163+
}
164+
}
165+
public:
166+
vector < vector < int >> permute(vector < int > & nums) {
167+
vector < vector < int >> ans;
168+
recurPermute(0, nums, ans);
169+
return ans;
170+
}
171+
};
172+
```
173+
174+
```Java
175+
class Solution {
176+
private void recurPermute(int index, int[] nums, List < List < Integer >> ans) {
177+
if (index == nums.length) {
178+
// copy the ds to ans
179+
List < Integer > ds = new ArrayList < > ();
180+
for (int i = 0; i < nums.length; i++) {
181+
ds.add(nums[i]);
182+
}
183+
ans.add(new ArrayList < > (ds));
184+
return;
185+
}
186+
for (int i = index; i < nums.length; i++) {
187+
swap(i, index, nums);
188+
recurPermute(index + 1, nums, ans);
189+
swap(i, index, nums);
190+
}
191+
}
192+
private void swap(int i, int j, int[] nums) {
193+
int t = nums[i];
194+
nums[i] = nums[j];
195+
nums[j] = t;
196+
}
197+
public List < List < Integer >> permute(int[] nums) {
198+
List < List < Integer >> ans = new ArrayList < > ();
199+
recurPermute(0, nums, ans);
200+
return ans;
201+
}
202+
};
203+
```
204+
205+
### Complexity Analysis
206+
207+
- **Time complexity**: O(N! X N)
208+
- **Space complexity**: O(1)
209+
210+
211+
### Conclusion
212+
213+
1. Recursive DP with Memoization: Efficiently avoids redundant calculations but has higher time complexity.
214+
2. Iterative DP with Tabulation: Iteratively solves for each position but has quadratic time complexity.
215+
3. Greedy BFS: Provides the most optimal solution with linear time complexity and constant space, making it the best approach for this problem.

0 commit comments

Comments
 (0)