全排列問題

          求一個數組或者string的全排列是很經典的問題。解決此類問題,首先在自己大腦思考,通常自己求一個數組的全排列會怎麼求,比如arr[1, 2, 3],答案是:[1, 2, 3]、[1, 3, 2]、[2, 1, 3]、[2, 3, 1]、[3, 2, 1]、[3, 1, 2]。思路就是:從第一個字符開始和後面的字符進行交換,再從第二個字符開始和後面的進行交換,再第n-1和第n個交換。這樣能夠保證不會遺漏一些排列。

46Permutations---利用回溯來做全排列

題目描述:

Given a collection of distinct numbers, return all possible permutations.

For example,
[1,2,3] have the following permutations:

[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]


題目解析:

1.此題求全排列,並且數組中沒有重複的數,那麼其實比較簡單。依次交換不會出現重複解。
2. 利用遞歸回溯來做,交換完一個位置到最後求出解返回後。復原,再依次交換當前位置和下一個交換位置,保證遍歷到所有解。

代碼如下:

class Solution {
public:
    // 使用遞歸回溯來解決此問題:此題沒有重複字符,可以這樣寫
    void permute(vector<int>& nums, int size, int start, vector<vector<int>> &out)
    {
        if(start == size-1)
        {
            out.push_back(nums);
            return;
        }
        for(int i=start; i<size; ++i)
        {
            // 交換
            int temp = nums[i];
            nums[i] = nums[start];
            nums[start] = temp;
            // 遞歸求解
            permute(nums, size, start+1, out);
            // 回溯復原
             temp = nums[i];
            nums[i] = nums[start];
            nums[start] = temp;   
        }
        return;
    }
    vector<vector<int>> permute(vector<int>& nums) 
    {
        vector<vector<int>> out;
        if(nums.empty())
            return out;
        permute(nums, nums.size(), 0, out);
        
        return out;
    }
};

47Permutations II---遞歸回溯

問題描述:

Given a collection of numbers that might contain duplicates, return all possible unique permutations.

For example,
[1,1,2] have the following unique permutations:

[
  [1,1,2],
  [1,2,1],
  [2,1,1]
]

問題解析:

1. 此題也是求全排列。較上一題的不同點是此題的arr中可能出現重複數字。
2.因此此題需要在遞歸回溯時候做處理,首先,兩個位置的數字相同就沒有必要交換了,因爲交換完結果是一樣的,節省遞歸次數,直接跳過當前被交換位置就行。
3. 其次,在結果集中做個處理,使用set來存儲結果集,避免出現重複結果。


代碼如下:

class Solution {
public:
    // 使用遞歸回溯來解決此問題
    void permute(vector<int>& nums, int size, int start, set<vector<int>> &out)
    {
        if(start == size-1)
        {
            out.insert(nums);
            return;
        }
        for(int i=start; i<size; ++i)
        {
            if(i!=start && nums[i] == nums[start])
                continue;
            int temp = nums[i];
            nums[i] = nums[start];
            nums[start] = temp;
            permute(nums, size, start+1, out);
             temp = nums[i];
            nums[i] = nums[start];
            nums[start] = temp;   
        }
        return;
    }

    vector<vector<int>> permuteUnique(vector<int>& nums) 
    {
        set<vector<int>> out;
        permute(nums, nums.size(), 0, out);
        
        return vector<vector<int>>(out.begin(), out.end());
    }
};


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