【LeetCode】46. Permutations 寻找全排列

一、概述

输入n个元素,找其全排列A^n_n 。

第一眼看上去有点懵,然后就开始DFS。用unordered_set当哈希表来记录当前序列已经有的值,然后遍历剩余的值。

想法特别简单,时空复杂度还好。

但是这方法明显不好——肯定不是最优解。

最优解没有用set,使用很多次的swap实现的。

二、分析

1、我的方法

直接深搜,每在序列中加入一个元素,就把这个元素加入set,最后将序列加入结果中。代码如下:

class Solution {
    vector<vector<int> > res;
    unordered_set<int> s;
    void DFS(vector<int>& tmp,int now,int n,vector<int>& nums)
    {
        if(now==n)
        {
            res.push_back(tmp);
            return;
        }
        else
        {
            for(int i=0;i<n;++i)
            {
                if(s.find(nums[i])==s.end())
                {
                    s.insert(nums[i]);
                    tmp.push_back(nums[i]);
                    DFS(tmp,now+1,n,nums);
                    tmp.pop_back();
                    s.erase(nums[i]);
                }
            }
        }
    }
public:
    vector<vector<int>> permute(vector<int>& nums) {
        int n=nums.size();
        vector<int> tmp;
        DFS(tmp,0,n,nums);
        return res;
    }
};

很直白,容易想到,但是效率不高。

2、较好的方法

我们以输入1、2、3、4为例,输出可以是:

1、2、3、4

           4、3

      3、2、4

           4、2

      4、2、3

           3、2

这样1开头的就完事了。观察我写序列的这个顺序,第一个和第二个是1、2、3、4和1、2、4、3,最后两个调换位置。之后是1、3、2、4,从1、2系列改成了1、3系列,可以看做2、3调换位置。然后继续最后两个调换位置。接下来1、2变成1、4可以看成3、2调换位置。说明本质上,序列的生成就是一系列调换位置的结果。比如说上面六个序列的生成:

1不动,2和2换,3和3换;

1不动,2和2换,3和4换;

1不动,2和3换,2和2换;

1不动,2和3换,2和4换;

1不动,2和4换,2和2换;

1不动,2和4换,2和3换;

就相当于第一次调换为2和2、3、4换,第二次调换也一样。

整体来看,第一次相当于1和1换,之后1和2、3、4换,生成所有序列。

这也是DFS。但是比我的好多了。如下:

class Solution {
    vector<vector<int> > res;
    void DFS(int now,int n,vector<int>& nums)
    {
        if(now==n)
        {
            res.push_back(nums);
            return;
        }
        else
        {
            for(int i=now;i<n;++i)
            {
                swap(nums[now],nums[i]);
                DFS(now+1,n,nums);
                swap(nums[i],nums[now]);
            }
        }
    }
public:
    vector<vector<int>> permute(vector<int>& nums) {
        int n=nums.size();
        vector<int> tmp;
        DFS(0,n,nums);
        return res;
    }
};

三、总结

序列处理中,这个swap函数实在是太重要了。很多很好的想法都是通过它实现的。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章