给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例 1:
- 输入:nums = [1,2,3]
- 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
示例 2:
- 输入:nums = [0,1]
- 输出:[[0,1],[1,0]]
示例 3:
- 输入:nums = [1]
- 输出:[[1]]
提示:
- 1 <= nums.length <= 6
- -10 <= nums[i] <= 10
- nums 中的所有整数 互不相同
Method:
由于排列问题会使用到所有的元素,因此需要设置一个use_flag数组来记录元素是否被使用过,在遍历时,需要跳过已经使用的元素。
使用回溯法来遍历不同的排列,回溯的终止条件是:缓存temp的大小等于nums的大小,说明搜索到了叶节点,保存结果后返回。
Code:
- class Solution{
- public:
- // 全排列
-
- // 使用回溯法遍历所有可能的排列方式
- void Recall(vector<int> &nums, vector<int> &temp, vector
int >> &result, vector<bool> &use_flag){ - // 如果当前缓存的结果长度等于给定的数组长度
- if(temp.size()==nums.size()){
- // 则回溯结束
- // 记录当前缓存的结果
- result.push_back(temp);
- }
- // 从0开始遍历给定的数组
- for(int i=0;i
size();i++){ - // 如果当前数字已经被使用
- if(use_flag[i]==true){
- // 则跳过该数字
- continue;
- }
- // 如果当前数字未被使用
- // 将当前数字设置为已使用
- use_flag[i]=true;
- // 将当前数字加入缓存中
- temp.push_back(nums[i]);
- // 回溯搜索接下来的排列
- Recall(nums, temp, result, use_flag);
- // 搜索完毕后将该数字移出缓存
- temp.pop_back();
- // 取消该数字的使用记录
- use_flag[i]=false;
- }
- }
-
- // 全排列
- vector
int>> permute(vector<int> &nums){ - // 记录所有结果
- vector
int>> result; - // 临时保存一组结果
- vector<int> temp;
- // 记录数组中的数是否被使用
- vector<bool> use_flag(nums.size(),false);
- // 如果给定数组的长度为1
- if(nums.size()==1){
- // 则最终结果只有一种可能
- temp.push_back(nums[0]);
- result.push_back(temp);
- }
- else{
- // 如果给定数组的长度大于1
- // 则开始回溯所有可能的排列方式
- Recall(nums, temp, result, use_flag);
- }
- return result;
- }
- };
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/permutations
Reference: