47. Permutations II
Given a collection of numbers, nums
, that might contain duplicates, return all possible unique permutations in any order.
Constraints:
1 <= nums.length <= 8
-10 <= nums[i] <= 10
Example 1:
Input: nums = [1,1,2]
Output:
[[1,1,2],
[1,2,1],
[2,1,1]]
Example 2:
Input: nums = [1,2,3]
Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
包含重复元素的全排列问题 ,与不包含重复元素的全排列问题不同,需要避免生成重复的排列。使用回溯算法,并通过剪枝来确保生成的排列唯一。
cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 回溯函数
void backtrack(vector<int>& nums, vector<vector<int>>& result, int start) {
// 如果当前起始位置是数组的最后一个元素,说明找到一个排列
if (start == nums.size()) {
result.push_back(nums); // 将当前排列存入结果
return;
}
// 用于记录当前层已经使用过的数字,避免重复
vector<bool> used(21, false); // 数字范围在 -10 到 10 之间
// 从起始位置开始,尝试交换元素
for (int i = start; i < nums.size(); i++) {
// 如果当前数字已经使用过,跳过
if (used[nums[i] + 10]) { // +10 是为了将负数映射到正数
continue;
}
used[nums[i] + 10] = true; // 标记当前数字已使用
swap(nums[start], nums[i]); // 交换元素
backtrack(nums, result, start + 1); // 递归到下一个位置
swap(nums[start], nums[i]); // 回溯,撤销交换
}
}
// 主函数:生成所有唯一排列
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<vector<int>> result; // 存储所有唯一排列
backtrack(nums, result, 0); // 从第 0 个位置开始回溯
return result;
}