题解 | #没有重复项数字的所有排列#

没有重复项数字的所有排列

http://www.nowcoder.com/practice/4bcf3081067a4d028f95acee3ddcd2b1

题目的主要信息:

  • 给出一组数字,返回该组数字的所有排列
  • 数字无重复
  • 以数字在数组中的位置靠前为优先级,按字典序排列输出

方法一:递归

具体做法:

可以通过递归,每次递归对每个下标的元素与它后面每个元素交换位置成为一种排列的情况,当下标到了数组结尾即可认为一种排列加入答案中。当某一种交换的结果经过了所有递归,需要进行回溯,以保证每种情况都有。如下图所示: alt

class Solution {
public:
    void recursion(vector<vector<int> > &res, vector<int> & num, int index){
        if(index == num.size() - 1) //分枝进入结尾,找到一种排列
            res.push_back(num);
        else{
            for(int i = index; i < num.size(); i++){ //遍历后续的元素
                swap(num[i], num[index]); //交换二者
                recursion(res, num, index + 1); //继续往后找
                swap(num[i], num[index]); //回溯
            }
        }
    }
    vector<vector<int> > permute(vector<int> &num) {
        sort(num.begin(), num.end()); //先按字典序排序
        vector<vector<int> > res;
        recursion(res, num, 0); // 递归获取
        return res;
    }
};

复杂度分析:

  • 时间复杂度:O(n!)O(n!)nn个元素的数组进行全排列
  • 空间复杂度:O(n)O(n),递归栈深度为nn,其中返回矩阵res属于必要空间,不属于额外空间

方法二:库函数

具体做法:

可以使用next_permutation函数获取该数组全排列,因为该函数每次是获取字典序下的下一个排列,因此要先对原数组进行排序,排成升序后才能调用函数。

class Solution {
public:
    vector<vector<int> > permute(vector<int> &num) {
        sort(num.begin(), num.end()); //先按字典序排序
        vector<vector<int> > res;
        do{
            res.push_back(num);
        }while(next_permutation(num.begin(), num.end())); //全排列函数
        return res;
    }
};

复杂度分析:

  • 时间复杂度:O(n!)O(n!)nn个元素的数组进行全排列
  • 空间复杂度:O(1)O(1),返回矩阵res属于必要空间,不属于额外空间
孤帆远影碧空尽 文章被收录于专栏

牛客网各类题单题解~

全部评论
写的不错啊,流程图看着很清晰,但是有个问题,就是递归的时候应该每轮都进行一次排序,否则好像没法维持字典序输出,比如[2,-1,3]这组输入,不排序的话最后的输入顺序就会变成[3,2,-1]和[3,-1,2]了
点赞 回复 分享
发布于 2022-03-23 09:39

相关推荐

轻絵梨花泪沾衣:南泵,大少爷驾到通通闪开
点赞 评论 收藏
分享
11-19 18:44
已编辑
成都理工大学 Java
程序员花海:我面试过100+校招生,大厂后端面试不看ACM,竞赛经历含金量低于你有几份大厂实习 这个简历整体来看不错 可以海投
如何写一份好简历
点赞 评论 收藏
分享
评论
5
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务