题目(leecode T46):
给定一个不含重复数字的数组 nums
,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
方法:全排列是数学中的基础问题,也是回溯算法能解决的经典问题。全排列因为每个元素都会用到,所以不需要startIndex来控制递归的位置,但由于每个元素只能使用一次而不重复,所以需要使用used数组来表示当前元素是否被使用过了,使用过的话就跳过当前递归。分析三部曲:
1:传入参数与返回值:传入nums数组与使用数组used
2:终止条件:全排列要求每个元素都用到了,因此当path中收集的元素长度达到了nums.size时就可以收集结果并返回了
3:单层处理逻辑:单层中只需要判断一下当前的nums[i]是否是被使用过的,如果是的话就直接退出当前递归,否则的话就递归。同时记得在处理nums[i]元素时更新used数组的使用情况。
题解:
class Solution {
private:
vector<int> path;
vector<vector<int>> result;
void backtracking(vector<int>& nums, vector<bool>& used){
if(path.size() == nums.size()){ //终止条件
result.push_back(path);
return;
}
for(int i = 0; i < nums.size(); i++){ //因为每个元素都要用到,无需startIndex
if(used[i] == true) continue;
path.push_back(nums[i]);
used[i] = true; //注意及时更新used数组
backtracking(nums, used);
path.pop_back();
used[i] = false;
}
}
public:
vector<vector<int>> permute(vector<int>& nums) {
path.clear();
result.clear();
vector<bool> used(nums.size(), false); //used数组刚开始默认是全false的
backtracking(nums, used);
return result;
}
};