LeetCode/solutions/46. Permutations.md
2019-01-12 12:29:18 +08:00

62 lines
2.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# [46. Permutations](https://leetcode.com/problems/permutations/)
# 思路
返回一个数组的所有排列,数组中元素没有重复。
如果做了[31. Next Permutation](https://leetcode.com/problems/next-permutation/)的话那这题就没什么问题了。稍有不同的是此题的数组元素没有重复而39题中可能重复。
所以此题可以使用STL中现成的next_permutation函数
> bool next_permutation (first, last)返回的是bool型如果已经是最后一个排列了则返回false并将数组变成第一个排列(即按照从小到大排好序)否则返回true并将数组变成下一个排列。
此外还可以传入comp参数: next_permutation (first, last, comp)这样就可以自定义数组的大小规则。
另外也可手动实现这个函数,参见我的[31题题解](https://github.com/ShusenTang/LeetCode/blob/master/solutions/31.%20Next%20Permutation.md)。
亲测使用STL中的要比手动实现慢很多。
# C++
## 使用STL中的next_permutation
``` C++
class Solution {
public:
vector<vector<int>> permute(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;
}
};
```
## 手动实现(亲测更快)
``` 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--;
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;
else low = mid + 1;
}
// int high = len - 1;
// while(nums[i - 1] > nums[high]) high--;
swap(nums[i - 1], nums[high]);
reverse(nums.begin() + i, nums.end());
return true;
}
public:
vector<vector<int>> permute(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;
}
};
```