题目
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
分析
标记数组
每次枚举一个位置$pos$的可能的值,当前枚举的值在标记数组中标记,然后继续枚举下一个位置。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
   | class Solution { public:     vector<vector<int>> permute(vector<int>& nums) {         cur = vector<int>(nums.size(), 0);         vis = vector<bool>(nums.size(), false);         backtrace(nums, 0);         return ans;     }     void backtrack(vector<int>& nums, int pos)     {         if (pos == nums.size())         {             ans.push_back(cur);             return;         }         for (int i = 0; i < nums.size(); ++i)         {             if (vis[i]) continue;             vis[i] = true;             cur[pos] = nums[i];             backtrace(nums, pos + 1);             vis[i] = false;         }     } private:     vector<vector<int>> ans;     vector<int> cur;     vector<bool> vis; };
 
  | 
 
空间复杂度:$O(n)$
原地
我们可以将当前枚举的元素交换到数组的前端,使得$[0, pos]$的元素是枚举过的元素,而$[pos + 1, n - 1]$的元素是尚未枚举过的元素,这样枚举下个位置的时候直接从$pos+1$开始枚举,就能保证枚举的元素一定是未枚举过的元素。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
   | class Solution { public:     vector<vector<int>> permute(vector<int>& nums) {         backtrack(nums, 0);         return ans;     }     void backtrack(vector<int> &nums, int pos)     {         if (pos == nums.size())         {             ans.push_back(nums);             return;         }         for (int i = pos; i < nums.size(); ++i)         {             swap(nums[i], nums[pos]);             backtrack(nums, pos + 1);             swap(nums[i], nums[pos]);         }     } private:     vector<vector<int>> ans; };
 
  | 
 
空间复杂度:$O(1)$.