1、描述
64给定一个 没有重复 数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/permutations
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2、关键字
全排列、回溯、DFS
3、思路
回溯、深度优先
4、notes
1、java种的contains函数,C++种find没找到怎么用,就换了一个<bool>的vector
回溯算法:3个问题?
1、路径:也就是已经做出的选择。(track 在累加路径)
2、选择列表:也就是你当前可以做的选择。 (在剩下的nums中寻找)
3、结束条件:也就是到达决策树底层,无法再做选择的条件。
回溯框架
result = []
def backtrack(路径, 选择列表):
if 满足结束条件:
result.add(路径)
return
for 选择 in 选择列表:
做选择
backtrack(路径, 选择列表)
撤销选择
其核心就是 for 循环里面的递归,在递归调用之前「做选择」,在递归调用之后「撤销选择」
参考解析:https://leetcode-cn.com/problems/permutations/solution/hui-su-suan-fa-xiang-jie-by-labuladong-2/
5、复杂度
时间:O(n*n!)
空间:O(n)
6、code
class Solution {
private:
vector<vector<int>> res; // 最后答案
public:
vector<vector<int>> permute(vector<int>& nums) { // 主函数调用
vector<bool>flag(nums.size(),true); // 作为访问过与否的标志位
vector<int> track; // 已经选择的路径
backtrack(track,nums, flag); // 调用递归函数
return res;
}
void backtrack(vector<int>& track,vector<int>& nums,vector<bool>&flag)
{
//触底返回
if(track.size()==nums.size())
{
res.emplace_back(track); // 一个解
return;
}
//
for(int i=0;i<nums.size();i++)
{
if(flag[i]) // 没被访问过,才从此处往下去
{
track.push_back(nums[i]); // 做选择
flag[i]=false;
//进入下一层
backtrack(track,nums,flag);
//撤销动作
//track.erase(track.end()-1);
track.pop_back();
flag[i]=true;
}
}
}
};