生成排列
用数组P[1…n]来存放每一个排列。
算法一:
假定可以生成n-1个数的所有排列,那么就可以扩展方法来生成1,2,… ,n这n个数的排列,方法如下。生成数2,3,…, n的所有排列,并且在每个排列的前面加上数1,接下来,生成数1,3,4, … ,n的所有排列,并且在每个排列的前面加上数2.重复这个过程直到最后生成1,2,… ,n-1的所有 排列,并且在每个排列的前面加上数n。这个方法在算法PERMUTATIONS1中描述。注意当P[j]和P[m]在递归调用前进行了交换时,它们必须在递归调用后交换回来。
算法 PERMUTATIONS1
输入: 正整数n。
输出:数1,2,…,n的所有可能排列。
1. for j ← 1 to n
2. P[j] ← j
3. end for
4. perml(1)
过程 perml(m)
1. if m = n then output P[1…n]
2. else
3. for j ← m to n
4. 互换 P[j] 和 P[m]
5. perml(m+1)
6. 互换P[j]和P[m]
7. comment: 这时P[m…n] = m, m + 1, … , n
8. end for
9. end if
C++ 代码, 在leetcode上为AC。
class Solution {
public:
void swap(int& a, int& b) {
int tmp = a;
a = b;
b = tmp;
}
vector<vector<int>> ret;
void perm(vector<int>& nums, int begin) {
if (begin == nums.size() - 1) {
ret.push_back(nums);
}
else {
for (int j = begin; j < nums.size(); j++) {
swap(nums[j], nums[begin]);
perm(nums, begin + 1);
swap(nums[j], nums[begin]);
}
}
}
vector<vector<int>> permute(vector<int>& nums) {
perm(nums, 0);
return ret;
}
};
算法二:
假定有办法生成数1,2,… , n-1的所有的排列,那么就可以扩展它来产生n个数的所有排列,方法如下。首先把n放入P[1],并且在P[2…n]子数组中生成前n-1个数的所有排列。接下来把n放入P[2],并且在子数组P[1]和[3…n]中生成前n-1个数的所有排列。然后把n放入P[3], 并且在子数组P[1…2]和P[4…n]中生成前n-1个数的所有排列。这样继续下去,直到最后把n放到P[n]中,并且在子数组P[1…n-1]中生成n-1个数的所有排列。初始的时候,P[1…n]的n个项为0,这个方法在算法PERMUTATIONS2中描述。
算法 PERMUTATIONS2
输入:正整数n。
输出:数1,2,…,n的所有可能排列。
1. for j ←1 to n
2. P[j] ← 0
3. end for
4. perm2(n)
过程 perm2(m)
1. if m ← 0 then output P[1…n]
2. else
3. for j ← 1 to n
4. if P[j] = 0 then
5. P[j] ← m
6. perm2(m-1)
7. P[j] ← 0
8. end if
9. end for
10. end if