LeetCode46. Permutations
Given a collection of distinct integers, return all possible permutations.
Example:
Input: [1,2,3]
Output:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
法1.回溯法。递归。每次交换num中的两个数字。第一个数字固定,对后面的数字进行全排列。输出所有全排列数字之后,还原最初的num。再重复第一步:交换第一个数字和后面的数字。
细节:结束条件start==num.size()。每次交换后的num在输出所有全排列之后要还原到最初的num。
class Solution {
public:
vector<vector<int>> permute(vector<int> &num) {
vector<vector<int>> ret;
Helper(num,ret,0);
return ret;
}
void Helper(vector<int> num,vector<vector<int>> & ret,int start)
{
if(start==num.size())
{
//一种全排列
ret.push_back(num);
}
for(int i = start ; i<num.size() ; i++)
{
swap(num[i],num[start]);//交换当前
Helper(num,ret,start+1);//进入下一层布局(后部分全排列)
swap(num[i],num[start]);//回到上一层布局
}
}
};
法2.递归。回溯。申请一个空数组out,长度为num大小。从out的第一个空位置开始,在num中选一个数填入out。用数组visited来表示num的元素是否访问过。一直到递归到index=size的时候,打印。每次打印完之后,要回溯到上一位,并且visited恢复为未访问。
class Solution {
public:
vector<vector<int>> permute(vector<int> &num) {
vector<vector<int>> ret;
if(num.size()==0) return ret;
vector<int> out,visited(num.size(),0);
Helper(num,out,ret,0,visited);
return ret;
}
void Helper(vector<int> num,vector<int> & out,
vector<vector<int>> &ret,int &index,vector<int> &visited)//int index不能用引用,他是const
{
if(index == num.size())
{
//一次排列完成
ret.push_back(out);
return;
}
for(int i =0 ;i<num.size();i++)
{
if(visited[i]==1)
continue;
visited[i]=1;
out.push_back(num[i]);
Helper(num,out,ret,index+1,visited);
out.pop_back();
visited[i]=0;
}
}
};
细节。 关于index的形参定义:不能用左值引用!因为无法传递常数进去,常数是无法更改的!
void Helper(vector<int> num,vector<int> & out,vector<vector<int>> &ret,int &level,vector<int> &visited);
//定义错误 形参不能设置为左值引用。
Helper(num,out,ret,0,visited);
cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'
0作为常量,只能做右值。所以不能用非常量左值引用作为形参。