算法笔记练习 题解合集
题目
题目描述
排列与组合是常用的数学方法。
先给一个正整数 ( 1 < = n < = 10 )
例如n=3,所有组合,并且按字典序输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
输入
输入一个整数n( 1<=n<=10)
输出
输出所有全排列
每个全排列一行,相邻两个数用空格隔开(最后一个数后面没有空格)
样例输入
3
样例输出
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
思路
- 递归版本思路:算法笔记 P115
- 迭代版本的思路:Next lexicographical permutation algorithm,这篇博客配合例子讲解得十分清楚,我看完一遍就实现了代码,强烈推荐!
- 库函数
next_permutation
版本:std::next_permutation
代码
递归版本
#include <iostream>
#include <vector>
using namespace std;
int n;
vector<int> ans(11);
vector<bool> hashTable(11, false);
void DFS(int index) {
if (index > n) {
for (int i = 1; i <= n; ++i) {
if (i != 1)
putchar(' ');
printf("%d", ans[i]);
}
putchar('\n');
return;
}
for (int i = 1; i <= n; ++i) {
if (hashTable[i] == false) {
ans[index] = i;
hashTable[i] = true;
DFS(index + 1);
hashTable[i] = false;
}
}
}
int main() {
while(scanf("%d", &n) != EOF)
DFS(1);
return 0;
}
迭代版本
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool myNextPermutation(vector<int>& nums) {
int pivot, pos;
for (pivot = nums.size() - 1; pivot > 0 && nums[pivot - 1] >= nums[pivot]; --pivot)
continue;
if (pivot == 0)
return false;
--pivot;
for (pos = pivot; pos < nums.size() - 1 && nums[pos + 1] >= nums[pivot]; ++pos)
continue;
swap(nums[pivot], nums[pos]);
reverse(nums.begin() + pivot + 1, nums.end());
return true;
}
int main() {
int n;
while (scanf("%d", &n) != EOF) {
vector<int> nums(n);
for (int i = 1; i <= n; ++i)
nums[i - 1] = i;
do {
for (int i = 0; i < n; ++i) {
if (i > 0)
putchar(' ');
printf("%d", nums[i]);
}
putchar('\n');
} while (myNextPermutation(nums));
}
return 0;
}
库函数next_permutation
版本
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int n;
while (scanf("%d", &n) != EOF) {
vector<int> nums(n);
for (int i = 1; i <= n; ++i)
nums[i - 1] = i;
do {
for (int i = 0; i < n; ++i) {
if (i > 0)
putchar(' ');
printf("%d", nums[i]);
}
putchar('\n');
} while (next_permutation(nums.begin(), nums.end()));
}
return 0;
}