1. 程式人生 > >題15:全排列(不帶重複元素)

題15:全排列(不帶重複元素)

題目描述:

給定一個數字列表,返回其所有可能的排列。
例如:
給出一個列表[1,2,3],其全排列為:
[
[1, 2, 3],
[1, 3, 2],
[2, 1, 3],
[2, 3, 1],
[3, 1, 2],
[3, 2, 1]
]

思路1:

從集合中依次選出每一個元素作為排列的第一個元素,然後對剩餘的元素進行全排列,如此遞迴從而得到全排列。例如:
固定1,求後面2,3的排列123,132,求完後交換1和2得到213,
固定2,求後面1,3的排列213,231,求完後3放到第一個位置321,
固定3,求後面1,2的排列321,312

程式碼:

class Solution
{
public:
    vector<vector<int>> permute(vector<int> &num) 
    {
        vector<vector<int>> res;
        if(num.size() == 0)
            return res;
        vector<int> tempres;
        permuteRecur(num, 0, res, tempres);
        return
res; } void permuteRecur(vector<int> &num, int index, vector<vector<int>> &res, vector<int> &tempres) { if(index == num.size()) { res.push_back(tempres); return; } for(int i = index; i < num.size(); i++) { swap(num[index], num[i]); tempres.push_back(num[index]); permuteRecur(num, index+1
, res, tempres); tempres.pop_back(); swap(num[index], num[i]); } } };

思路2:

採用DFS深搜的辦法,並用一個數組標記該元素是否被訪問過。

class Solution 
{  
public:  
    vector<vector<int>> permute(vector<int> &num)
    {  
        vector<vector<int>> res;  
        vector<int> cur;  

        int n=num.size();  
        if(n == 0)
        {  
            return res;  
        }  
        int *bit=new int[n];    //表示該元素是否被訪問過
        memset(bit,0,sizeof(int)*n);  

        DFS(res,cur,num,0,bit);  

        return  res;  
    }  
private:  
   void DFS(vector<vector<int>> &res,vector<int> &cur,vector<int> &num,int count,int *bit)
   {  
       int n=num.size();  
       if(count==n)
       {  
            res.push_back(cur);  
            return;  
       }  
       for(int i=0;i<n;i++)
       {  
          if(!bit[i])
          {  
             cur.push_back(num[i]);  
             bit[i]=1;  
             DFS(res,cur,num,count+1,bit);  
             bit[i]=0;  
             cur.pop_back();  
          }  
       }  
    }  
};