Given a collection of 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], and [3,2,1].
题目意思很直白,求出不重复的所有排列,这里的是数字,对于字符串同样适用。
思路一:递归,每次都按照nums的顺序访问并且加入当前的vector,再递归的下一层。如果当前层的vector的大小==nums的大小,则是一个合理的排列。否则,按顺序遍历nums的每一个元素,如果该元素没有被加入vector则加入继续递归。
所以这里需要有个标记是否访问过的visted数组,加入vector时设为true表示访问了,这样在下次递归时就不会使用。退出时再设为false表示未访问。
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> permus;
if(nums.size()==0) return permus;
vector<bool> visted(nums.size(),false);
vector<int> curr; //记录当前层的排列
backTracking(permus,curr,visted,nums);
}
void backTracking(vector<vector<int>>& permus, vector<int> curr, vector<bool>& visted, vector<int>& nums){
if(curr.size()==nums.size()){
permus.push_back(curr);
return;
}
for(int i = 0; iif(visted[i]==false){
visted[i]=true;
curr.push_back(nums[i]);
backTracking(permus,curr,visted,nums);
visted[i]=false;
curr.pop_back();
}
}
}
};
这种思路和 combination和combination II很像
输出为
1234 1243 1324 1342 1423 1432.。。。
AC 20ms
思路二:以123为例
123 132 213 231 312 321
对于每一层来说我们有当前的下标begin,有循环下标i,我们交换begin和i的值(包括begin和自己交换),下一层递归就会产生交换后的所有排列。一旦递归返回,再交换回来,这样就回到了起点123.i变成1,交换变成213,递归。
class Solution {
public:
vector<vector<int> > permute(vector<int> &num) {
vector<vector<int> > result;
permuteRecursive(num, 0, result);
return result;
}
// permute num[begin..end]
// invariant: num[0..begin-1] have been fixed/permuted
void permuteRecursive(vector<int> &num, int begin, vector<vector<int> > &result) {
if (begin >= num.size()) {
// one permutation instance
result.push_back(num);
return;
}
for (int i = begin; i < num.size(); i++) {
swap(num[begin], num[i]);
permuteRecursive(num, begin + 1, result);
// reset
swap(num[begin], num[i]);
}
}
};
输出
123 132 213 231 312 321
AC 12ms
这里还有一个输入字符串,输出字符串排列的操作
void swap(char *fir, char *sec)
{
char temp = *fir;
*fir = *sec;
*sec = temp;
}
/* arr is the string, curr is the current index to start permutation from and size is sizeof the arr */
void permutation(char * arr, int curr, int size)
{
if(curr == size-1)
{
for(int a=0; a"\t";
cout << endl;
}
else
{
for(int i=curr; i1, size);
swap(&arr[curr], &arr[i]);
}
}
}
int main()
{
char str[] = "abcd";
permutation(str, 0, sizeof(str)-1);
return 0;
}
对于第k层节点来说,就是交换固定了前面 k-1 位,然后分别 swap(k,k), swap(k, k+1) , swap(k, k+2)
…例如上图中的第三层,固定了第一位(即2),然后分别交换第1,1位,1,2位,1,3位
思路三:这里还有一种插入的方法,
当只有1时候:[1]
当加入2以后:[2, 1], [1, 2]
当加入3以后:[3, 2, 1], [2, 3, 1], [2, 1,3], [3, 1, 2], [1, 3, 2], [1, 2, 3]
前3个permutation分别对应将3插入[2, 1]的0, 1, 2的位置。同理后3个为插入[1, 2]的。因此可以用逐个插入数字来构造所有permutations。
class Solution {
public:
vector<vector<int> > permute(vector<int> &num) {
vector<vector<int>> allPer;
if(num.empty()) return allPer;
allPer.push_back(vector<int>(1,num[0]));
for(int i=1; iint n = allPer.size();
for(int j=0; jfor(int k=0; kvector<int> per = allPer[j];
per.insert(per.begin()+k, num[i]);
allPer.push_back(per);
}
allPer[j].push_back(num[i]);
}
}
return allPer;
}
};
AC 18ms