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

没有重复项数字的全排列

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

方法一:递归+回溯

全排列就是对数组元素交换位置,使每一种排列都可能出现。因为题目要求按照字典序排列输出,那毫无疑问第一个排列就是数组的升序排列,它的字典序最小,后续每个元素与它后面的元素交换一次位置就是一种排列情况,但是如果要保持原来的位置不变,那就不应该从它后面的元素开始交换而是从自己开始交换才能保证原来的位置不变,不会漏情况。

具体做法:

  • step 1:先将数组排序,获取字典序最小的排列情况。
  • step 2:递归的时候根据当前下标,遍历后续的元素,交换二者位置后,进入下一层递归。
  • step 3:处理完一分支的递归后,将交换的情况再换回来进行回溯,进入其他分支。
  • step 4:当前下标到达数组末尾就是一种排列情况。

该方法好像无法按照字典序输出?

时间复杂度:o(n*n!)

空间复杂度:o(n)

class Solution {
  public:
    void resort(vector<vector<int> >& res, vector<int>& num, int idx) {
	  	//到达最后一个元素输出
        if (idx == num.size() - 1) {
            res.push_back(num);
        } else {
            for (int i = idx; i < num.size(); i++) {
                swap(num[i], num[idx]);
                resort(res, num, idx + 1);
                swap(num[i], num[idx]);
            }
        }
    }

    vector<vector<int> > permute(vector<int>& num) {
        vector<vector<int> > res;
        //先对数组进行排序
        sort(num.begin(), num.end());
        resort(res, num, 0);

        return res;
    }
};

方法二:递归+dfs

将数组抽象为数,利用深度优先可以搜索得到所有的情况。

该方法可以按照字典序的顺序输出

时间复杂度:o(n*n!)

空间复杂度:o(n)

class Solution {
  public:
    void dfs(vector<int>& num, vector<bool>& flag, int idx) {
        if (idx == num.size()) {
            res.push_back(temp);
        } else {
            for (int i = 0; i < num.size(); i++) {
                if (flag[i] == false) {
                    //数字未被选取时压入数组
                    flag[i] = true;
                    temp.push_back(num[i]);
                    dfs(num, flag, idx + 1);
                    //回溯
                    temp.pop_back();
                    flag[i] = false;
                }
            }
        }
    }
    vector<vector<int> > permute(vector<int>& num) {
        //用来判断数字是否被选取
        vector<bool> flag(num.size(), false);
        dfs(num, flag, 0);

        return res;
    }

  private:
    vector<int> temp;
    vector<vector<int> > res;
};

刷题题解(c++) 文章被收录于专栏

算法题题解(c++)

全部评论

相关推荐

07-11 22:27
中南大学 Java
程序员牛肉:学历的话没问题。但是没问题的也就只有学历了。 其实你的整体架构是正确的,博客接着干。但是项目有点过于简单了。从后端的角度上讲,你这也就是刚入门的水平,所以肯定约面试够呛。 如果你要应聘后端岗位,那你第一个项目竟然是仿写操作系统。这个你要面试官咋问你。你一定要记住一点,你简历上写的所有的东西,都是为了证明你有能力胜任当前的岗位,而不是为了证明你自己会什么。 如果你只是浅浅的做几个项目,描述也都是烂大街。技术点也都是各种混水类的配置类需求,那你就不要幻想自己能走多远。一定要保持思考,保持学习。
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

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