全排列算法问题
2016-12-05 15:00
162 查看
ACM经典算法题目
输入n,输出1~n的全排列
如输入:3
输出:
如图:
![](http://i.imgur.com/4qfKpvI.png)
关于这个问题要如何实现呢:
大家可以自己先思考一下,下面我说一下答案。
这其实是一道简单的深度优先搜索的题目
代码:
结果:
![](http://i.imgur.com/ahBgCMb.png)
如果对代码有问题的小伙伴我猜是对这一段代码块不理解
其实不难:设定一个used数组用来标记当前元素是否已经被访问,如果没有被访问过则进入if代码块,将当前元素填入perm数组中(perm数组是用来记录全排列元素的顺序的)并将used数组置为true,并递归调用此函数。那么问题来了,为什么要在后面加一个把used数组又重置为false呢?其实这就是dfs的回溯(相信有的小伙伴已经明白了)。比如:123下一个排列是132,为什么能产生132呢,就是因为当本次递归到出口后,又将used数组重置为false才能够继续访问2和3,先重置元素3,再重置元素2,这就是回溯。
那么到这里还没有结束,因为c++标准库为我们提供了一种更加便捷的方式(记得要加头文件algorithm):
代码:
结果:
![](http://i.imgur.com/PWqp1pa.png)
是不是感觉又轻松了不少呢!
输入n,输出1~n的全排列
如输入:3
输出:
123 132 ……
如图:
![](http://i.imgur.com/4qfKpvI.png)
关于这个问题要如何实现呢:
大家可以自己先思考一下,下面我说一下答案。
这其实是一道简单的深度优先搜索的题目
代码:
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; #define MAX_N 1000 bool used[MAX_N]; int perm[MAX_N]; void permutation1(int pos, int n) { if(pos == n) { for(int i = 0; i < n; i++) { printf("%d ", perm[i]); } printf("\n"); return ; } for(int i = 0; i < n; i++) { if(!used[i]) { perm[pos] = i; used[i] = true; permutation1(pos+1, n); used[i] = false; } } return ; } int main() { int n; scanf("%d", &n); permutation1(1, n+1); return 0; }
结果:
![](http://i.imgur.com/ahBgCMb.png)
如果对代码有问题的小伙伴我猜是对这一段代码块不理解
for(int i = 0; i < n; i++) { if(!used[i]) { perm[pos] = i; used[i] = true; permutation1(pos+1, n); used[i] = false; } }
其实不难:设定一个used数组用来标记当前元素是否已经被访问,如果没有被访问过则进入if代码块,将当前元素填入perm数组中(perm数组是用来记录全排列元素的顺序的)并将used数组置为true,并递归调用此函数。那么问题来了,为什么要在后面加一个把used数组又重置为false呢?其实这就是dfs的回溯(相信有的小伙伴已经明白了)。比如:123下一个排列是132,为什么能产生132呢,就是因为当本次递归到出口后,又将used数组重置为false才能够继续访问2和3,先重置元素3,再重置元素2,这就是回溯。
那么到这里还没有结束,因为c++标准库为我们提供了一种更加便捷的方式(记得要加头文件algorithm):
代码:
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; #define MAX_N 1000 int perm2[MAX_N]; void permutation2(int n) { for(int i = 0; i < n; i++) { perm2[i] = i; } do{ for(int i = 0; i < n; i++) printf("%d ", perm2[i]); printf("\n"); }while(next_permutation(perm2, perm2+n)); return ; } int main() { int n; scanf("%d", &n); permutation2(n); return 0; }
结果:
![](http://i.imgur.com/PWqp1pa.png)
是不是感觉又轻松了不少呢!
相关文章推荐
- 算法之排列问题
- 【算法分析与设计】全排列问题
- 算法java实现--回溯法--圆排列问题--排列树
- 0002算法笔记——【递归】排列问题,整数划分问题,Hanoi问题
- 【算法面试】写程序输出8皇后问题的所有排列,要求使用非递归的深度优先遍历。
- 排列组合问题的通用算法
- c语言实现排列组合算法问题
- c语言实现排列组合算法问题
- 0039算法笔记——【分支限界法】电路板排列问题
- 算法实现(1)排列问题
- 求全排列问题的算法
- 算法题-排列组合问题
- 排列组合问题的通用算法
- 算法 全排列问题,组合问题,子集问题
- 全排列算法递归及STL实现,八皇后问题
- 排列组合之排列问题的算法实现
- 恶补算法与数据结构(一)——排列问题
- 〖編程·C++〗回溯算法:排列树 - 工作分配问题
- 数据结构与算法问题 [NOIP2001]求先序排列
- 算法实现(2)有重复元素的排列问题