//给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。
//
//
//
// 示例 1:
//
//
//输入:nums = [1,1,2]
//输出:
//[[1,1,2],
// [1,2,1],
// [2,1,1]]
//
//
// 示例 2:
//
//
//输入:nums = [1,2,3]
//输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
//
//
//
//
// 提示:
//
//
// 1 <= nums.length <= 8
// -10 <= nums[i] <= 10
//
// Related Topics 回溯算法
// 👍 609 👎 0
/*
* 47 全排列 II
* 2021-02-28 13:16:50
* @author oxygenbytes
*/
#include "leetcode.h"
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public:
vector<vector<int>> ans;
vector<int> path;
vector<bool> vis;
vector<vector<int>> permuteUnique(vector<int>& nums) {
int n = nums.size();
sort(nums.begin(), nums.end());
vis = vector<bool>(n, false);
dfs(nums, 0);
return ans;
}
void dfs(const vector<int>& nums, int cur){
if(cur == nums.size()){
ans.push_back(path);
return ;
}
// 例如[1 2 2‘]可能出现[1 2 2'] 和[1 2‘ 2] 的情况 如果“存在前一个相同元素” 且“未被使用过”, 当现有排列是[1 2']时
// 原来的数组[1 2 2‘]中2’存在前一个元素2与其相同, 且此时2未被访问过,跳过。[1 2 2']的排列先于[1 2' 2]存在,因此可以去除。
for(int i = 0;i < nums.size();i++){
if(!vis[i]){
vis[i] = true;
path.push_back(nums[i]);
dfs(nums, cur + 1);
path.pop_back();
vis[i] = false;
// [2,2',3] if cur(0) == 2, then skip cur(1)
while(i + 1< nums.size() && nums[i] == nums[i+1]) i++; // here is while
}
}
}
};
//leetcode submit region end(Prohibit modification and deletion)