2021年3月18日木曜日天気は良い[過去を嘆いたり、現在を無駄にしたり、未来を恐れたりしないでください]
1.はじめに
2.問題解決(Dafaを振り返る)
2.1一時配列法
class Solution {
public:
unordered_set<int> uset; // 利用哈希表判断元素是否遍历过了
vector<vector<int>> res;
vector<vector<int>> permute(vector<int>& nums) {
vector<int> tmp; // 临时数组,存放每一个排列的结果
dfs(nums,tmp,0);
return res;
}
void dfs(vector<int>& nums, vector<int>& tmp, int n){
// 终止条件,所有位都遍历完了
if(n==nums.size()){
res.push_back(tmp);
return;
}
for(int num:nums){
// 如果 num 还没有遍历
if(uset.find(num)==uset.end()){
// 加入哈希表和临时数组
uset.insert(num);
tmp.push_back(num);
// 继续遍历下一位
dfs(nums,tmp,n+1);
// 遍历完之后记得还原,避免分支污染
uset.erase(num);
tmp.pop_back();
}
}
}
};
これは私が最初にそれをしたときに書いた答えであり、理解しやすいです。合格することはできますが、公式の方法(下記の交換方法)よりも時間がかかります。
2.2交換方法
class Solution {
public:
void backtrack(vector<vector<int>>& res, vector<int>& output, int first, int len){
// 所有数都填完了
if (first == len) {
res.emplace_back(output);
return;
}
for (int i = first; i < len; ++i) {
// 动态维护数组
swap(output[i], output[first]);
// 继续递归填下一个数
backtrack(res, output, first + 1, len);
// 撤销操作
swap(output[i], output[first]);
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int> > res;
backtrack(res, nums, 0, (int)nums.size());
return res;
}
};
交換方式も完全配置問題を解決するための標準的な方式であり、コードは単純ですが、理解するのに少し手間がかかります。
次の図は理解に役立ちます。
*複雑さの分析
時間計算量の計算は理解するのがより困難です。次の図を参照して理解することができます。
各レイヤーの交換の数を合計すると、呼び出しの総数を取得できます。
次に、上記の式を導き出すことができます。
参照
https://leetcode-cn.com/problems/permutations/solution/quan-pai-lie-by-leetcode-solution-2/
https://blog.csdn.net/u013905744/article/details/113779407