题目:
- 给定一个不含重复数字的数组
nums
,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例:
- 输入: n u m s = [ 1 , 2 , 3 ] nums = [1,2,3] nums=[1,2,3]
- 输出: [ [ 1 , 2 , 3 ] , [ 1 , 3 , 2 ] , [ 2 , 1 , 3 ] , [ 2 , 3 , 1 ] , [ 3 , 1 , 2 ] , [ 3 , 2 , 1 ] ] [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
解题思路:
- 定义二维数组
res
用于存放结果;定义一维数组path
用于存放遍历的数;定义一维bool
数组used
用于判断是否使用过。 - 使用回溯算法(模板在此),每遍历一个数先判断是否使用过,没有使用过才加进
path
中。 - 递归结束条件:当
path
的大小等于输入数组nums
的大小,即代表遍历完了所有数,将该遍历方案加入结果集,并返回。
class Solution {
public:
vector<vector<int>> res; // 结果集
vector<int> path; // 方案集
vector<vector<int>> permute(vector<int>& nums) {
vector<bool> used(nums.size(), false); // 定义标记数组
backtracking(nums, used);
return res;
}
void backtracking(vector<int>& nums, vector<bool> used){
if(path.size() == nums.size()){ // 递归结束条件
res.push_back(path); // 将方案加入结果集
return;
}
for(int i = 0; i < nums.size(); i++){
if(used[i]){ // 使用过就跳过该数
continue;
}
path.push_back(nums[i]); // 加入该数
used[i] = true; // 标记该数使用过
backtracking(nums, used); //递归它
path.pop_back(); // 回溯它,恢复
used[i] = false; // 回溯它,恢复
}
}
};
时间复杂度:
O
(
n
!
∗
n
)
O(n! * n)
O(n!∗n)
空间复杂度:
O
(
n
)
O(n)
O(n)