【leetcode】【medium】46. Permutations

46. Permutations

Given a collection of distinct integers, return all possible permutations.

Example:

Input: [1,2,3]
Output:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

题目链接:https://leetcode-cn.com/problems/permutations/

思路

法一:回溯法

之前遇到的问题都是取连续的链,本题要取的元素并不连续。

这边用了一个数组在标记元素是否用过了,能够保证元素有重复值的情况也能使用。

class Solution {
public:
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int>> res;
        if(nums.size()<=0) return res;
        bool visit[nums.size()] = {false};
        return trace(nums, visit);
    }
    vector<vector<int>> trace(vector<int> nums, bool visit[]){
        vector<vector<int>> res;
        for (int i = 0; i<nums.size(); ++i){
            if(!visit[i]){
                visit[i] = true;
                auto vec = trace(nums, visit);
                visit[i] = false;
                if(vec.size()<=0){
                    vector<int> tmp = {nums[i]};
                    res.push_back(tmp);
                }else{
                    for(int j = 0; j<vec.size(); ++j){
                        vec[j].push_back(nums[i]);
                        res.push_back(vec[j]);
                    }
                }
            }
        }
        return res;
    }
};

代码优化

上面的代码是向下递归的时候进行了一次循环,返回结果后又对结果做了循环。

如果把两次循环合并,不是把下面结果向上传,而是上面的结果向下传到底后直接储存,可以降低运行时间。

class Solution {
public:
    vector<vector<int>> res;
    vector<vector<int>> permute(vector<int>& nums) {
        if(nums.size()<=0) return res;
        bool visit[nums.size()] = {false};
        vector<int> cur;
        trace(nums, 0, cur, visit);
        return res;
    }
    void trace(vector<int> nums, int index, vector<int> &cur, bool visit[]){
        if(index==nums.size()){
            res.push_back(cur);
            return;
        }
        for (int i = 0; i<nums.size(); ++i){
            if(!visit[i]){
                cur.push_back(nums[i]);
                visit[i] = true;
                trace(nums, index+1, cur, visit);
                visit[i] = false;
                cur.pop_back();
            }
        }
    }
};

法二:库函数next_permutation

这个方法是看分享才知道的。说实话有点作弊,做笔试或比赛的时候可以用,面试的话肯定还会细问next_permutation的实现。

next_permutation(开始位置,结束位置-不包含):变换范围 [first, last) 为来自所有按相对于 operator< 或 comp 的字典序的下个排列。若这种排列存在则返回 true ,否则变换范围为首个排列(如同用 std::sort(first, last) )并返回 false 。

这种方法应该属于特殊例子,没有仔细调研来龙去脉,暂时先参考这篇博文的解释学习了下,如果思路比较通用的话以后应该还会遇到,暂时先挖个坑背诵一下哈哈。

c++<algorithm>库中的解释:https://zh.cppreference.com/w/cpp/algorithm/next_permutation

代码来源:https://leetcode-cn.com/problems/permutations/solution/hui-su-next_permutation-by-ogeazjciet/

vector<vector<int>> permute(vector<int>& nums) {        
    sort(nums.begin(), nums.end());
    do {
        result.push_back(nums);
    }while (next_permutation(nums.begin(), nums.end()));
    return result;
}
发布了126 篇原创文章 · 获赞 2 · 访问量 3722

猜你喜欢

转载自blog.csdn.net/lemonade13/article/details/104516349