題15:全排列(不帶重複元素)
阿新 • • 發佈:2019-02-14
題目描述:
給定一個數字列表,返回其所有可能的排列。
例如:
給出一個列表[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();
}
}
}
};