题目描述
给定可能包含重复的数字集合,返回所有可能的惟一排列。例如,[1,1,2]有以下独特的排列:[1,1,2],[1,2,1],[2,1,1]。
解题思路
1. 解决重复数字问题
先对容器num进行排序,保证重复数字相邻,这样在后续操作中,利用条件,若后一数与前一数相等,则不处理
2、解决数字是否进入排列list容器问题
使用额外bool类型容器used,区分当前值是否已进入排列当中
3、解决排列问题
(1)若list长度等于num,则压入容器res
(2)对容器num进行for循环
边界条件:
- 若当前值已使用过,不处理;
- 若当前值与前一值相等,且前一值未使用过,不处理
(举例:112,循环第一个1作第一位时,第二位是第二个1,会被记录,但是循环第二个1做第一位时,第二位是第一个1,就不会被记录,避免重复)
当前值压入并依次作为排列list的元素,将used容器对应位置true
将当前list、num、used和res送入排列函数,进行递归
将used中对应位置false,list弹出当前值,继续for循环
代码示例
class Solution {
public:
vector<vector<int> > permuteUnique(vector<int> &num) {
vector<vector<int>> res;
if (num.size() == 0)
return res;
sort(num.begin(), num.end());
vector<bool> used(num.size());
vector<int> list;
permute(num, used, list, res);
return res;
}
void permute(vector<int>& num, vector<bool>& used, vector<int>& list, vector<vector<int>>& res) {
if (list.size() == num.size()) {
res.push_back(list);
return;
}
for (int i = 0; i < num.size(); i++) {
if (used[i])
continue;
if (i > 0 && num[i - 1] == num[i] && !used[i - 1])
continue;
used[i] = true;
list.push_back(num[i]);
permute(num, used, list, res);
used[i] = false;
list.pop_back();
}
}
};