Update 47. Permutations II.md

This commit is contained in:
唐树森 2019-03-16 15:24:00 +08:00 committed by GitHub
parent 8ef87a4300
commit 0b8ab7293e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,11 +1,19 @@
# [47. Permutations II](https://leetcode.com/problems/permutations-ii/)
# 思路
返回一个数组的所有排列数组中元素可能有重复。注意和46题对比
## 思路一、Next Permutation
有了[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)即可很容易写出代码。
## 思路二、DFS常规思路务必掌握
类似46题此题常规思路就是用DFS做与46题不同的是此题中数组可能有重复元素。所以我们先对nums进行排序这样重复的元素总是挨着的。
为了避免重复结果的产生在递归函数中要判断前面一个数和当前的数是否相等如果相等且其对应的visited中的值为false需要跳过因为前面一个数字和当前数字
相等的话前面的数字未被使用的话当前数字也不应该被使用。
# C++
## 使用STL中的next_permutations(完全同46题)
## 思路一、Next Permutation
### 使用STL中的next_permutations(完全同46题)
``` C++
class Solution {
public:
@ -19,7 +27,7 @@ public:
}
};
```
## 手动实现
### 手动实现
``` C++
class Solution {
private:
@ -54,3 +62,34 @@ public:
}
};
```
## 思路二、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;
}
};
````