[LC]46.全排列

题目

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

分析

标记数组

每次枚举一个位置$pos$的可能的值,当前枚举的值在标记数组中标记,然后继续枚举下一个位置。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
cur = vector<int>(nums.size(), 0);
vis = vector<bool>(nums.size(), false);
backtrace(nums, 0);
return ans;
}
void backtrack(vector<int>& nums, int pos)
{
if (pos == nums.size())
{
ans.push_back(cur);
return;
}
for (int i = 0; i < nums.size(); ++i)
{
if (vis[i]) continue;
vis[i] = true;
cur[pos] = nums[i];
backtrace(nums, pos + 1);
vis[i] = false;
}
}
private:
vector<vector<int>> ans;
vector<int> cur;
vector<bool> vis;
};

空间复杂度:$O(n)$

原地

我们可以将当前枚举的元素交换到数组的前端,使得$[0, pos]$的元素是枚举过的元素,而$[pos + 1, n - 1]$的元素是尚未枚举过的元素,这样枚举下个位置的时候直接从$pos+1$开始枚举,就能保证枚举的元素一定是未枚举过的元素。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
backtrack(nums, 0);
return ans;
}
void backtrack(vector<int> &nums, int pos)
{
if (pos == nums.size())
{
ans.push_back(nums);
return;
}
for (int i = pos; i < nums.size(); ++i)
{
swap(nums[i], nums[pos]);
backtrack(nums, pos + 1);
swap(nums[i], nums[pos]);
}
}
private:
vector<vector<int>> ans;
};

空间复杂度:$O(1)$.


[LC]46.全排列
https://erlsrnby04.github.io/2024/10/18/LC-46-全排列/
作者
ErlsrnBy04
发布于
2024年10月18日
许可协议