全排列 II
给定一个可包含重复数字的序列
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
题目重点在于理解回溯的原理(每次回溯都在找下一个位置填的数,需要保证下标不重复,即同一个数不能重复取)
本题还需要进一步去重
去重:对于某个位置重复数只能取1次,否则就会出现大量的重复排列,对应到程序里,即每一次回溯的for循环里要排除掉重复数
题解1 回溯
class Solution {
vector<vector<int>> ret;
vector<bool> used;
deque<int> track;
public:
void backtrace(vector<int>& nums){
if(track.size() == nums.size()){
ret.push_back(vector<int>(track.begin(), track.end()));
return;
}
for(int i = 0; i < nums.size(); i++){
// 当used[i - 1] == 0时,说明nums[i - 1]和nums[i]属于同一层递归中(只是for循环进入下一层循环,即同一个位置取数,位置已经重复了)
// 当used[i - 1] == 1时, 说明在不同位置上,不需要去重
if(used[i] || (i && nums[i] == nums[i-1] && ! used[i-1])) continue;
used[i] = true;
track.push_back(nums[i]);
// 下一个位置
backtrace(nums);
track.pop_back();
used[i] = false;
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
used.resize(nums.size());
sort(nums.begin(), nums.end());
backtrace(nums);
// set<vector<int>> s (ret.begin(), ret.end());
// ret.assign(s.begin(), s.end());
return ret;
}
};