- 全排列 II
给定一个可包含重复数字的序列,返回所有不重复的全排列。
示例:
输入: [1,1,2]
输出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
全排列的问主要有两种思路:
使用 used[i] 布尔数组记录元素是否使用过;
使用交换的方式,在深度优先遍历(回溯)的过程中生成。
给出一个速度较快的代码
class Solution {
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
sort(nums.begin(), nums.end());
int current_len = 0;
vector<vector<int>> res;
function<void(void)> backtrack = [&](void){
if(current_len == nums.size()){
res.push_back(nums);
return;
}
current_len++;
backtrack();
current_len--;
for(int i = 0; i < current_len; i++){
if(nums[i] == nums[current_len]) break;
swap(nums[i], nums[current_len]);
current_len++;
backtrack();
current_len--;
swap(nums[i], nums[current_len]);
}
};
backtrack();
return res;
}
};
作者:tai-yang-tian
链接:https://leetcode-cn.com/problems/permutations-ii/solution/shuang-bai-si-lu-chao-ji-jian-ji-by-tai-yang-tian/
这个做法使用交换完成
同样的:
class Solution {
vector<vector<int>> ans;
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
sort(nums.begin(), nums.end());
perm(nums, 0, nums.size() - 1);
return ans;
}
void perm(vector<int> nums, int left, int right) {
if (left == right)
ans.push_back(nums);
else {
for (int i = left; i <= right; i++) {
if (i != left && nums[left] == nums[i]) continue;
swap(nums[left], nums[i]);
perm(nums, left + 1, right);
}
}
}
};