LeetCode46--Permutations

這一題本質上就是求全排列,求全排列有很多種方式,這裏我使用了一種我平時用的比較多的方法。
思路:當我們想要去求"1 2 3 4"的全排列時,我們只需要枚舉出來即可。使用四個for循環 啊不當然不是,這個方法只適用於初學for循環纔會考慮。我們想求"1234"全排列,其實就是求1開頭,剩下數字自由組合 + 2開頭,剩下數字互相組合 + 3 開頭,剩下數字互相組合 + 4 開頭,剩下數字自由組合即可。
爲了方便分析,我們把原來要求的說成4維全排列,所以我們需要讓1在第一位,並降低規模求3維的全排列,再讓2在第一位,降低規模求3維的全排列…當我們求三維全排列時,又需要固定一個數字在第一位,求更低規模的全排列。這實際上就是遞歸的思路了,所以我們只要想辦法讓不同的數字來到第一位,就可以得到這個數字打頭的所有排列了。
那我們怎麼把不同的數換到第一位上來呢?我們用循環當前位後面的分別與當前位做交換,讓他們都體驗一下打頭的滋味,同時,打頭後我們則需要降低規模,保持當前位前面的數不變,去求後面的排列了。當我們處理到第n位時,一種排列就完成了。實際上,如果單純只是做一遍交換再降低規模,排列是會重複的,所以我們把2開頭的算完排列後,還是需要把1放回到最前面來,保持原來的隊形再把1與3交換,這樣下去,每次一個數算完後,都會使得數列回覆到這次調用前的樣子,就不會重複啦。
好啦,Show Code:

#include<algorithm>
class Solution {
public:
    void Test(vector<vector<int>> &res,vector<int> &nums,int k)
    {
        //若已經到最後了,則無需運算了,把nums放進去即可
        if(k == nums.size()-1)
        {
            res.push_back(nums);
            return;
        }
            
        for(int i = k;i < nums.size();++i)
        {
            swap(nums[i],nums[k]);
            Test(res,nums,k+1);
            swap(nums[i],nums[k]);
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        //求全排列
        vector<vector<int>> res;
        if(nums.size() == 0)
            return res;
        Test(res,nums,0);
        return res;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章