【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函數實在是太重要了。很多很好的想法都是通過它實現的。

 

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