2019-01-12 08:51:27 +00:00
# [47. Permutations II](https://leetcode.com/problems/permutations-ii/)
# 思路
2019-03-16 07:24:00 +00:00
返回一个数组的所有排列, 数组中元素可能有重复。( 注意和46题对比)
## 思路一、Next Permutation
2019-01-12 08:51:27 +00:00
有了[31. Next Permutation](https://leetcode.com/problems/next-permutation/)和[46. Permutations](https://leetcode.com/problems/permutations/)的做题经验,这题就显得是一个送分题了。
这题与46题唯一区别就是此题允许重复元素, 所以需要注意在元素比较的时候相等的情况。参考[46的题解](https://github.com/ShusenTang/LeetCode/blob/master/solutions/46.%20Permutations.md)即可很容易写出代码。
2019-03-16 07:24:00 +00:00
## 思路二、DFS( 常规思路, 务必掌握)
类似46题, 此题常规思路就是用DFS做, 与46题不同的是此题中数组可能有重复元素。所以我们先对nums进行排序, 这样重复的元素总是挨着的。
为了避免重复结果的产生, 在递归函数中要判断前面一个数和当前的数是否相等, 如果相等, 且其对应的visited中的值为false, 需要跳过, 因为前面一个数字和当前数字
相等的话前面的数字未被使用的话当前数字也不应该被使用。
2019-01-12 08:51:27 +00:00
# C++
2019-03-16 07:24:00 +00:00
## 思路一、Next Permutation
### 使用STL中的next_permutations(完全同46题)
2019-01-12 08:51:27 +00:00
``` C++
class Solution {
public:
vector< vector < int > > permuteUnique(vector< int > & nums) {
vector< vector < int > >res;
if(nums.empty()) return res;
sort(nums.begin(), nums.end()); // 先排序
res.push_back(nums);
while(next_permutation(nums.begin(), nums.end())) res.push_back(nums);
return res;
}
};
```
2019-03-16 07:24:00 +00:00
### 手动实现
2019-01-12 08:51:27 +00:00
``` C++
class Solution {
private:
bool my_next_permute(vector< int > & nums){
int len = nums.size();
int i = len - 1;
while(i > 0 & & nums[i] < = nums[i - 1]) i--; // 与46题的不同点一
if(i == 0) return false;
int mid, low = i, high = len - 1;
while(low < = high){ // 二分查找
mid = low + (high - low) / 2;
if(nums[mid] < = nums[i - 1]) high = mid - 1; // 与46题的不同点二
else low = mid + 1;
}
// int high = len - 1;
// while(nums[i - 1] >= nums[high]) high--; // 与46题的不同点二
swap(nums[i - 1], nums[high]);
reverse(nums.begin() + i, nums.end());
return true;
}
public:
vector< vector < int > > permuteUnique(vector< int > & nums) {
vector< vector < int > >res;
if(nums.empty()) return res;
sort(nums.begin(), nums.end()); // 先排序
res.push_back(nums);
while(my_next_permute(nums)) res.push_back(nums);
return res;
}
};
```
2019-03-16 07:24:00 +00:00
## 思路二、DFS
``` C++
class Solution {
private:
void DFS(vector< vector < int > > & res, vector< bool > & visited, vector< int > & pmt, const vector< int > & nums){
if(pmt.size() == nums.size()){
res.push_back(pmt);
return;
}
for(int i = 0; i < nums.size ( ) ; i + + ) {
if(visited[i]) continue;
if(i > 0 & & nums[i] == nums[i - 1] & & !visited[i - 1]) continue; // 剪枝
visited[i] = true;
pmt.push_back(nums[i]);
DFS(res, visited, pmt, nums);
pmt.pop_back();
visited[i] = false;
}
}
public:
vector< vector < int > > permuteUnique(vector< int > & nums) {
vector< vector < int > >res;
if(nums.empty()) return res;
vector< bool > visited(nums.size(), false);
vector< int > pmt;
sort(nums.begin(), nums.end()); // 先排序
DFS(res, visited, pmt, nums);
return res;
}
};
````