多练习多练习
$\color{red}{思路}$
枚举Nums从前到后每一位数,并将该位数放在path数组的空闲位置。
关键是处理好重复数据的情况 : 枚举 nums 当前位 i 和 i - 1位相同,则在path中依然要保证重复数相对位置不变
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
vector<vector<int>> permutation(vector<int>& nums) {
path.resize(nums.size());
sort(nums.begin(), nums.end());
dfs(nums, 0, 0, 0);
return res;
}
/*
nums中的元素放在每一个坑上, nums第 k 个数放在第 i 个坑上, 第k + 1个数放在第 j 个坑上(i和j之前都没有放)
如果nums[k]和nums[k + 1]是相同的,那么nums[k + 1]要放在 i + 1 坑上,保持重复数字相对位置不变
*/
/*
u是当前枚举的位置,start是当前数应该从哪一位开始枚举,state是存状态
*/
// u 针对的是nums数组,是从 1 - nums.size() 依次取值的
void dfs(vector<int> &nums, int u, int start, int state) //start 存的是上一个开始的位置
{
if(u == nums.size())
{
res.push_back(path);
return;
}
/*
nums当前位置和上一个位置数不同,path数组可以从第0位枚举,看那个位置有空位。
如果相同,则必须从nums[n - 1]这个数所在path数组位置后面位开始查空位。保证
重复数字相对顺序一样。
*/
if(!u || nums[u] != nums[u - 1]) start = 0;
for(int i = start; i < nums.size(); ++ i)
{
if(!(state >> i & 1)) //path数组当前位置没有被用过
{
path[i] = nums[u]; //nums数组的第u位放在 path数组的第i位
dfs(nums, u + 1, i + 1, state + (1 << i));
}
}
}
};