# 面試題_回溯法

## 46. 全排列

1 <= nums.length <= 6
-10 <= nums[i] <= 10
nums 中的所有整數 互不相同

class Solution {
vector<vector<int> > ans;
vector<int> t;
public:
void dfs(vector<int>& nums, int cur, int nlen, vector<int>& used)
{
if (cur == nlen) {
ans.push_back(t);
return;
}
for(int i = 0; i < nlen; ++i)
{
if (!used[i]) {
t.push_back(nums[i]);
used[i] = true;
dfs(nums, cur + 1, nlen, used);
t.pop_back();
used[i] = false;
}
}
}
vector<vector<int>> permute(vector<int>& nums) {
int nlen = nums.size();
vector<int> used(nlen);
dfs(nums, 0, nlen, used);
return ans;
}
};

class Solution {
public:
void dfs(vector<vector<int> >& ans, vector<int>& nums, int first, int nlen)
{
if (first == nlen) {
ans.emplace_back(nums);
return;
}
for(int i = first; i < nlen; ++i)
{
swap(nums[i], nums[first]);
dfs(ans, nums, first + 1, nlen);
swap(nums[i], nums[first]);
}
}
vector<vector<int>> permute(vector<int>& nums)
{
vector<vector<int> > ans;
int nlen = nums.size();
dfs(ans, nums, 0, nlen);
return ans;
}
};


• 時間複雜度：$$O(n\times n!)$$，其中 n 爲序列的長度。
• 空間複雜度：O(n)

## 47. 全排列 II

[[1,1,2],
[1,2,1],
[2,1,1]]

1 <= nums.length <= 8
-10 <= nums[i] <= 10

class Solution {
vector<int> vis;
public:
void dfs(vector<vector<int> >& ans, vector<int>& nums, int cur, int nlen, vector<int>& perm)
{
if (cur == nlen) {
ans.emplace_back(perm);
return;
}
for (int i = 0; i < nlen; ++i)
{
if(vis[i] || (i > 0 && nums[i - 1] == nums[i] && vis[i - 1])) {
continue;
}
perm.emplace_back(nums[i]);
vis[i] = 1;
dfs(ans, nums, cur + 1, nlen, perm);
vis[i] = 0;
perm.pop_back();
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<int> perm;
vector<vector<int> > ans;
int nlen = nums.size();
vis.resize(nlen);
sort(nums.begin(), nums.end());
dfs(ans, nums, 0, nlen, perm);
return ans;
}
};


• 時間複雜度：$$O(n\times n!)$$，其中 n 爲序列的長度。
• 空間複雜度：O(n)

class Solution {
public:
bool nextpermute(vector<int>& nums)
{
int i = nums.size() - 2;
while (i >= 0 && nums[i] >= nums[i + 1]) i--;
if (i < 0) return false;
int j = nums.size() - 1;
while (j >= 0 && nums[i] >= nums[j]) j--;
if (j < 0) return false;
swap(nums[i], nums[j]);
reverse(nums.begin() + i + 1, nums.end());
return true;
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<vector<int> > ans;
sort(nums.begin(), nums.end());
do {
ans.emplace_back(nums);
} while (nextpermute(nums));
return ans;
}
};


## 劍指 Offer 38. 字符串的排列

1 <= s 的長度 <= 8

class Solution {
vector<int> vis;
public:
void dfs(vector<string>& ans, const string& s, int cur, int slen, string& perm)
{
if(cur == slen)
{
ans.emplace_back(perm);
return;
}
for (int i = 0; i < slen; ++i)
{
if(vis[i] || (i > 0 && s[i] == s[i - 1] && vis[i - 1])) {
continue;
}
perm.push_back(s[i]);
vis[i] = 1;
dfs(ans, s , cur + 1, slen, perm);
vis[i] = 0;
perm.pop_back();
}
}
vector<string> permutation(string s) {
int slen = s.size();
vis.resize(slen);
vector<string> ans;
string perm;
sort(s.begin(), s.end());
dfs(ans, s, 0, slen, perm);
return ans;
}
};



class Solution {
vector<string> ans;
public:
void dfs(string& s, int cur, int slen)
{
if (cur == slen - 1) {
ans.emplace_back(s);
return;
}
unordered_set<int> uset;
for(int i = cur; i < slen; i++)
{
if (uset.find(s[i]) != uset.end()) {
continue;
}
uset.insert(s[i]);
swap(s[i], s[cur]);
dfs(s, cur + 1, slen);
swap(s[i], s[cur]);
}
}
vector<string> permutation(string s) {

dfs(s, 0, s.length());
return ans;
}
};



class Solution {
public:
bool nextPermutation(string& s) {
int i = s.size() - 2;
while (i >= 0 && s[i] >= s[i + 1]) {
i--;
}
if (i < 0) {
return false;
}
int j = s.size() - 1;
while (j >= 0 && s[i] >= s[j]) {
j--;
}
swap(s[i], s[j]);
reverse(s.begin() + i + 1, s.end());
return true;
}

vector<string> permutation(string s) {
vector<string> ret;
sort(s.begin(), s.end());
do {
ret.push_back(s);
} while (nextPermutation(s));
return ret;
}
};