leetcode/notes/src/permute.md
Sainnhe Park 4d93e5a150
All checks were successful
ci/woodpecker/push/test Pipeline was successful
Update image url
2023-02-18 13:55:17 +08:00

92 lines
2.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 排列问题
排列问题N 个数按一定规则全排列,有几种排列方式
## [46. 全排列](https://leetcode.cn/problems/permutations/)
## [47. 全排列 II](https://leetcode.cn/problems/permutations-ii/)
和 s0046 相比就加了去重。有两种去重思路,一个是用哈希表记录每一层的使用情况,另一种是排序 + 判断,后者性能更好所以优先选择后者。
哈希表法:
```cpp
#include "s0047_permutations_ii.hpp"
void permuteUniqueDFS(vector<int> &path, vector<vector<int>> &result,
vector<bool> &used, vector<int> &nums) {
int len = nums.size();
// 终止条件
if (path.size() == len) {
result.push_back(path);
return;
}
// 创建一个哈希表用来记录当前层中使用过的元素
unordered_map<int, bool> map;
// 开始迭代
for (int i{0}; i < len; ++i) {
// 如果当前元素在树枝或树层使用过,则跳过
if (used[i] || map.count(nums[i]) == 1) continue;
// 否则处理当前节点
map[nums[i]] = true;
path.push_back(nums[i]);
used[i] = true;
permuteUniqueDFS(path, result, used, nums);
used[i] = false;
path.pop_back();
}
}
vector<vector<int>> S0047::permuteUnique(vector<int> &nums) {
vector<int> path{};
vector<vector<int>> result{};
vector<bool> used(nums.size(), false);
permuteUniqueDFS(path, result, used, nums);
return result;
}
```
排序 + 判断:
```cpp
void permuteUniqueDFS(vector<int> &path, vector<vector<int>> &result,
vector<bool> &used, vector<int> &nums, int startIndex) {
int len = nums.size();
// 终止条件
if (path.size() == len) {
result.push_back(path);
return;
}
// 开始迭代
for (int i{0}; i < len; ++i) {
// 如果当前元素在树层使用过,则跳过
if (used[i] || (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false))
continue;
// 否则处理当前节点
path.push_back(nums[i]);
used[i] = true;
permuteUniqueDFS(path, result, used, nums, i + 1);
used[i] = false;
path.pop_back();
}
}
vector<vector<int>> S0047::permuteUnique(vector<int> &nums) {
vector<int> path{};
vector<vector<int>> result{};
vector<bool> used(nums.size(), false);
sort(nums.begin(), nums.end());
permuteUniqueDFS(path, result, used, nums, 0);
return result;
}
```
## [332. 重新安排行程](https://leetcode.cn/problems/reconstruct-itinerary/)
这道题本来是想不到回溯法的,但是如果某道题能够拆分成多个步骤,每个步骤都在前一步的基础上进行选择,那么就可以用回溯法。
![demo](https://share.sainnhe.dev/ej8H.png)