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

2.3 KiB
Raw Blame History

46. Permutations

思路

返回一个数组的所有排列,数组中元素没有重复。
如果做了31. Next Permutation的话那这题就没什么问题了。稍有不同的是此题的数组元素没有重复而39题中可能重复。
所以此题可以使用STL中现成的next_permutation函数

bool next_permutation (first, last)返回的是bool型如果已经是最后一个排列了则返回false并将数组变成第一个排列(即按照从小到大排好序)否则返回true并将数组变成下一个排列。 此外还可以传入comp参数: next_permutation (first, last, comp)这样就可以自定义数组的大小规则。

另外也可手动实现这个函数,参见我的31题题解
亲测使用STL中的要比手动实现慢很多。

C++

使用STL中的next_permutation

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;
    }
};

手动实现(亲测更快)

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;
    }
};